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