C fread和fwrite将浮点矩阵从.dat文件保存到内存中的数组时出现问题

C fread和fwrite将浮点矩阵从.dat文件保存到内存中的数组时出现问题,c,c99,fwrite,fread,strtok,C,C99,Fwrite,Fread,Strtok,目标 我需要: 1。用fwrite将N*N矩阵写入二进制文件。矩阵是​​以N*N个元素的数组连续存储在内存中 2.分配另一个N*N数组,并使用fread读取先前创建的文件中的矩阵,将其逐个元素保存在新创建的数组中 3.在标准输出上打印新阵列 第一个数组是float*,第二个数组也必须是float* 我的代码 这是我的代码,它似乎在二进制文件中打印正确的矩阵,但当我用fread读取它并将其保存到新数组中时,当我打印新数组时,它只打印0.0.0 0 ecc void fileBinPrintMat(

目标

我需要:

1。
fwrite
将N*N矩阵写入二进制文件。矩阵是​​以N*N个元素的数组连续存储在内存中

2.分配另一个N*N数组,并使用
fread
读取先前创建的文件中的矩阵,将其逐个元素保存在新创建的数组中

3.在标准输出上打印新阵列

第一个数组是
float*
,第二个数组也必须是
float*

我的代码

这是我的代码,它似乎在二进制文件中打印正确的矩阵,但当我用
fread
读取它并将其保存到新数组中时,当我打印新数组时,它只打印
0.0.0 0 ecc

void fileBinPrintMat(float* a, int dim, FILE* output){
    float x;
    for(int i = 0; i < dim; i++){
          x = a[i];
          fwrite(&x, sizeof(float), 1, output);
    }
 }
   

     
#define DIM 512

//PART 1, PRINT THE MATRIX IN .dat FILE
int main(int argc, char** argv){
    .
    .
    .
    float* M1 = calloc(n*n, sizeof(float));
        CHECK_MEMORY(M1, "CALLOC"); //MACRO for checking allocation memory
        for(size_t i = 0; i < (n); i++)
            for(size_t j = 0; j < n; j++)
                M1[(i*n)+j] = (i+j)/2.0;
    FILE* ofpbin = fopen("mat_dump.dat", "wb");
    CHECK_OPEN_FILE(ofpbin, "mat_dump.dat");
    fileBinPrintMat(M1, n*n, ofpbin); //Function that print matrix in file.dat
    free(M1);
    fclose(ofpbin);

//PART 2, SAVE THE MATRIX PRINTED IN .dat FILE IN N*N ARRAY
    FILE* ifpbin = fopen("mat_dump.dat", "rb");
    CHECK_OPEN_FILE(ifpbin, "mat_dump.dat");
    char* buffer = calloc(DIM, sizeof(char));
    CHECK_MEMORY(buffer, "CALLOC");
    float* M2 = calloc(n*n, sizeof(float));
    CHECK_MEMORY(M2, "CALLOC"); 
//READ MATRIX FROM FILE AND WRITE IT IN ARRAY M2
    int i = 0;
    float elemBuffer;
    while(fgets(buffer, DIM, ifpbin) != NULL){
        fread(&elemBuffer, sizeof(float), 1, ifpbin);
        M2[i] = elemBuffer;
        i++;   
    }
    
二进制文件中的内容如下:

 ? ? �? �?
 ? �? �? @
 �? �? @  @
 �? @  @ @@
我认为没关系,它必须从.dat保存到数组
float*M2
如下:

0.0   0.5   1.0   1.5   0.5   1.0   1.5   2.0   1.0   1.5   2.0   2.5   1.5   2.0   2.5   3.0
 
我的输出

  0.0   0.0   0.0   0.0
  0.0   0.0   0.0   0.0
  0.0   0.0   0.0   0.0
  0.0   0.0   0.0   0.0
重要提示:


这是一个大学作业,我可以用fread和fwrite来表示二进制文件i/o,用strtok来表示文件中元素之间的空间。

处理二进制文件时,经验法则是读取文件的代码和写入文件的代码应该相同,但函数相反

我的意思是,在你的例子中,你有一个简单的循环,将一个连续的
float
值数组写入文件

这意味着,您的读取代码必须执行相同的操作—从文件中读取一个连续的浮点数组

在读取循环中添加额外的逻辑会使代码以错误的方式解析数据,这就是无法获取值的原因

因此,以下是您应该如何阅读它们:

void fileBinReadMat(float* a, int dim, FILE* input){
    float x;
    for(int i = 0; i < dim; i++){
          fread(&x, sizeof(float), 1, input);
          a[i] = x;
    }
}
void fileBinReadMat(float*a、int-dim、FILE*input){
浮动x;
对于(int i=0;i

严格地说,您不需要使用
x
中间变量来读取或写入,但我将其保留在那里是为了保持代码的一致性和易于理解。

如果您正在读取和写入二进制数据,您应该使用的唯一两个函数是
fread
fwrite
。你为什么要写反斜杠和空格?破坏了二进制文件的全部用途。宏只会让你的代码更难阅读,特别是在这里,你通常希望你的代码尽可能简单易懂。你对宏的看法是对的。我会编辑它。关于反斜杠和空格,我如何在二进制文件中写入空格来标记保存在其中的每个不同数字?您不需要在二进制文件中标记它们。每个
float
将恰好占用4个字节,因此它们之间不需要任何分隔符。好的,那么我不能将文件按列格式化为经典的N*N矩阵吗?二进制文件通常不会被视为文本文件。因此不需要格式化。如果你想打开那个文件,想看到一个格式整齐的矩阵,那么你可以使用文本文件。好的,它可以工作,所以如果我理解的很好,fread从文件中读取4字节,而不是将指针改为4字节?所以我不需要使用FGET?我也可以把它写成:
void fileBinReadMat(float*a,intdim,FILE*input){for(inti=0;i
@ClaudioDeLise
fgets
用于读取字符串(可打印字符),而不是读取存储为二进制的
float
,因此,你不需要它,也不能使用它。我不知道你们所说的“改进指针”是什么意思,但
fread
要做的是从文件中提取4个字节,并将它们放在你们给它的指针指向的内存中。您可以直接给它数组单元格的地址
fread(&a[i],sizeof(float),1,input)并且它可以正常工作
fread
不关心将字节放入哪个内存,只要您的程序合法拥有它。在阅读之前,不要忘记
calloc
malloc
数组!我试着向你解释我的“改进”。我看到我传递给
fread
,作为最后一个参数a
文件*
文件;在
for
的第一次迭代中,需要4个字节,并将它们复制到第一个参数中指针的内存中,在本例中为
a[0]
。如何在
for
的第二次迭代中
fread
复制
a[1]
中的第二个4字节。如果在第二次迭代中,我再次传递
FILE*
FILE,为什么他不复制前4个字节?@ClaudioDeLise不认为
FILE*
是常规指针。可以将其视为“使用文件的黑盒子”。它指向管理打开的文件的文件对象。它“知道”您从文件中读取了多少字节,并保留下一个要读取的字节的位置。这一切都是自动完成的。它不会读取您已经读取的字节,除非您使用
fseek
功能移动位置。
void fileBinReadMat(float* a, int dim, FILE* input){
    float x;
    for(int i = 0; i < dim; i++){
          fread(&x, sizeof(float), 1, input);
          a[i] = x;
    }
}