将2D数组(矩阵)保存为C中函数内的二进制

将2D数组(矩阵)保存为C中函数内的二进制,c,arrays,function,pointers,matrix,C,Arrays,Function,Pointers,Matrix,我基本上是想把一个大的2D数组(矩阵)保存在一个二进制函数中 正如现在一样(参见下面的第一个玩具代码),矩阵被转换为指向每行(?)中第一个元素的指针。函数saveToFile中的警告fwrite强调了这一点: 数组函数参数的大小将返回“int(*)[4]”的大小,而不是“int[3][4]” 我通过行*cols定义矩阵来解决这个问题 我想知道是否有一种简单的方法可以将矩阵作为数组的数组传递,而不是指向数组开头的一组指针,这样我就可以像在主程序中那样方便地保存和上传矩阵(请参见最后的玩具代码) 也

我基本上是想把一个大的2D数组(矩阵)保存在一个二进制函数中

正如现在一样(参见下面的第一个玩具代码),矩阵被转换为指向每行(?)中第一个元素的指针。函数
saveToFile
中的警告
fwrite
强调了这一点:

数组函数参数的大小将返回
“int(*)[4]”
的大小,而不是
“int[3][4]”

我通过
行*cols
定义矩阵来解决这个问题

我想知道是否有一种简单的方法可以将矩阵作为数组的数组传递,而不是指向数组开头的一组指针,这样我就可以像在主程序中那样方便地保存和上传矩阵(请参见最后的玩具代码)

也就是说,是否存在一种方法可以避免在
fwrite
fread
中需要
rows*cols

感谢所有的投入

第一个玩具代码:

# define rows 3
# define cols 4

void saveToFile(int matrix[rows][cols]){

FILE * fout = fopen("test.dat", "wb");                 // save
fwrite(matrix, sizeof(matrix), rows*cols, fout);
fclose(fout);
}

int main(int argc, const char * argv[])
{
int m1[rows][cols];
int m2 [rows][cols];

for (int i = 0; i<rows; i++) {
    for (int j=0; j<cols; j++) {
        m1[i][j]= i+j;
    }
}
saveToFile(m1);

FILE * fin = fopen("test.dat", "rb");                   // open
fread(m2, sizeof(m2), rows*cols, fin);
fclose(fin);

return 0;
}
# define rows 3
# define cols 4

int main(int argc, const char * argv[])
{
int m1[rows][cols];
int m2 [rows][cols];

for (int i = 0; i<rows; i++) {
    for (int j=0; j<cols; j++) {
        m1[i][j]= i+j;
    }
}

FILE * fout = fopen("test.dat", "wb");     // save
fwrite(m1, sizeof(m1), 1, fout);
fclose(fout);


FILE * fin = fopen("test.dat", "rb");      // open
fread(m2, sizeof(m2), 1,  fin);
fclose(fin);

return 0;
}
#定义第3行
#定义cols4
void saveToFile(整数矩阵[行][cols]){
FILE*fout=fopen(“test.dat”、“wb”);//保存
fwrite(矩阵,sizeof(矩阵),rows*cols,fout);
fclose(fout);
}
int main(int argc,const char*argv[]
{
int m1[行][cols];
整数m2[行][cols];

对于(int i=0;i哈哈,我希望你会喜欢我的解决方案,就像我现在找到它一样

你看,问题是,你正在将指针
m1
传递给函数
saveToFile
。你知道当你传递东西时会发生什么;为要保存的参数分配了一个等效大小的内存位置,内存位置被参数值的副本填充。最后,它只是一个副本。例如)

void asd( int qwe ) {
    qwe = 5;
}

int main( ) {
    int qwe = 1;
    asd( qwe );

    return 0;
}
在这里,
qwe
内部
main
没有改变,
qwe
内部
asd
main
中的不同

至少在C语言中,你不能期望一个数组作为一个整体通过一次操作被复制。在你的第一件玩具中,只发送指针的一个副本。程序自然可能不知道原始的是什么。好吧,实际上可能,因为你指定了行和列的数量,但无论如何,它不能

以下是解决方案: 您将不会传递
m1
,而是传递
m1
的地址,即
&m1
。您只需提交地址的副本,然后从该地址,您将从另一个函数访问实际和原始变量
m1
。如下所示:

void saveToFile( int (* matrix)[rows][cols] ) {
    // matrix as a pointer to a 2D array of integers
    printf( "%d\n", sizeof * matrix );
}

int main( ) {
    int m1[rows][cols];
    printf( "%d\n", sizeof m1 );
    saveToFile( &m1 );  // passing the address of m1
}
缺点:每当你想访问一个元素时,你必须用括号括住对
矩阵的每个引用,并在前面加一个星号。但我想这就是你想要它做的


让我也学到了一些东西,一些我已经知道的东西,实际上…只是我没有意识到。

fread
fwrite
不适合你的任务。相反,使用
fprintf
fscanf

int main(){
    FILE *fin = NULL, *fout = NULL;
    int c, i = 0, j = 0;
    int m1[rows][cols];
    int m2[rows][cols];

    fout = fopen("test.dat", "wb");
    if(fout == NULL){printf("Error reading file \n"); return 0;}

    for(i = 0; i < rows; i++) {
        for(j = 0; j < cols; j++) {
            m1[i][j]= i+j;
            fprintf(fout, "%d\n", m1[i][j]);
        }
    }

    fclose(fout);

    fin = fopen("test.dat", "rb"); 
    if(fin == NULL){printf("Error reading file \n"); return 0;}

    i = j = 0;
    while( (c = fscanf(fin, "%d", &m2[i][j])) != EOF ){
        j++;
        if(j == cols ){i++; j = 0;}
        if(i == rows){break;}
    }

    fclose(fin);

    return 0;
}
叫它

saveToFile(&m1[0][0]); //prototype void saveToFile(int *);

or

saveToFile(m1); //prototype void saveToFile(int **);
fread应为:

fread(m2, sizeof(**m2), rows*cols, fin);

在C. C++中,你可能会有一个模板函数,抱歉,数组作为指针在C.传递,你可以使用一个定义,或者矩阵的大小是函数的参数。,您必须恰好在一个系统上,其中sizeof(int)==sizeof(int*)。感谢您的输入。我已将原始代码更正为sizeof(*matrix)。再次感谢:)现在我感到困惑。您的意思是在第二个玩具示例中?我刚刚运行了该程序,它可以工作…?@userjuice是的,就像您的第二个玩具一样。我可以调用函数(就像你的第一个玩具)但是对我来说,编写代码的速度更快。只需向我解释前面的方法有什么问题。我已经使用大型矩阵多次运行了玩具示例2,并且效果很好。但是当我尝试使用Appelsins解决方案时,数据会损坏/程序崩溃一些reason@userjuicer前面的方法是什么?你的还是我的?第二个玩具代码是什么在2000x50矩阵上运行了很多次,没有任何问题。但是正如我所说的,当我使用write fread时,我发现dat文件在根据Thoappelsi创建的函数中被破坏。我知道哪里出了问题。Thx:)我现在开始工作了。传递指针是有效的,但是当我试图读取文件时,程序崩溃了。@UserJuice好吧,这不是问题所在,所以我没有进一步检查……除了我提供的修复之外,您的代码中还有一个错误:您不应该传递
sizeof(matrix)
m1
m2
,等等。作为
fwrite
fread
函数的第二个参数。第二个参数获取使用第一个参数推入的流中单个元素的大小。因此它们应该是
sizeof(m1[0][0])例如,如果您应用了我在这里提供的
&
*
修复,那么您的
fwrite
调用的第二个参数应该是
sizeof((*matrix)[0][0])
,然后它就可以工作了。
fread(m2, sizeof(**m2), rows*cols, fin);