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

时间:2014-03-17 22:36:31

标签: c arrays function pointers matrix

我基本上试图将二维数组(矩阵)作为二进制文件保存在函数中。

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

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

的大小

我通过rows*cols定义矩阵解决了这个问题。

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

也就是说,是否存在一种方法来规避rows*colsfwritefread的需求?

感谢所有输入。

第一个玩具代码:

# 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;
}

2 个答案:

答案 0 :(得分:0)

哈哈,我希望你能尽情享受我的解决方案,就像我现在找到的一样。

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

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

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

    return 0;
}

此处qwe内的main未更改,qwe内的asdmain中的m1不同。

至少在C中,您不能指望通过单个操作复制整个数组。在第一个玩具中,只发送指针的副本。当然,程序可能不知道原件是什么。嗯,实际上它可能,因为你既指定了行数和列数,但无论如何,它都不能。

以下是解决方案:

您不会传递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 } 。像这样:

matrix

缺点:只要你想访问一个元素,你就必须用括号括起每个{{1}}的引用,并在前面加一个星号。但这就是我认为您希望它做的事情。

让我也学到一些东西,我已经知道的东西,实际上......就是不是那么明白。

答案 1 :(得分:0)

freadfwrite不适合您的任务。而是使用fprintffscanf

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;
}

修改

void saveToFile(int *matrix){
    FILE *fout = fopen("test.dat", "wb"); // save

    fwrite(matrix, sizeof(matrix), rows*cols, fout);

    fclose(fout);
}

or

void saveToFile(int **matrix){
    FILE *fout = fopen("test.dat", "wb"); // save

    fwrite(matrix, sizeof(matrix), rows*cols, fout);

    fclose(fout);
}

并将其命名为

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

or

saveToFile(m1); //prototype void saveToFile(int **);
恐惧应该是:

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

瓦尔特