fread 和 fwrite 将浮点矩阵从 .dat 文件保存到内存中的数组时出现问题
Problems with fread and fwrite saving a float matrix from .dat file to array in memory
目标
我需要:
1.用fwrite
将一个N*N矩阵写入二进制文件。矩阵在内存中是连续存储的,是一个N * N个元素的数组。
2. 分配另一个 N*N 数组并使用 fread
读取先前创建的文件中的矩阵,将其逐个元素保存在新创建的文件中数组。
3. 在标准输出上打印新数组。
第一个数组是float*
,第二个数组也必须是float*
。
我的代码
这是我的代码,它似乎在二进制文件中打印了正确的矩阵,但是当我用 fread
读取它并将它保存到一个新数组中时,当我打印新数组时它只打印 0.0 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++;
}
P.S。我知道我必须检查 fread ecc 的所有 return 值...我稍后会做
期望输出
假设n = 4
,最终输出矩阵必须是:
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
在二进制文件中是这样的:
? ? �? �?
? �? �? @
�? �? @ @
�? @ @ @@
而且我认为没关系,它必须像这样从 .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,对文件中元素之间的 space 进行标记化 space。
使用二进制文件时,经验法则是从文件读取的代码和写入文件的代码应该相同,但功能相反。
我的意思是,在你的情况下,你有一个简单的循环,将 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;
}
}
严格来说,您不需要 x
中间变量来进行读取或写入,但我将其保留在那里以保持代码相同且更易于理解。
目标
我需要:
1.用fwrite
将一个N*N矩阵写入二进制文件。矩阵在内存中是连续存储的,是一个N * N个元素的数组。
2. 分配另一个 N*N 数组并使用 fread
读取先前创建的文件中的矩阵,将其逐个元素保存在新创建的文件中数组。
3. 在标准输出上打印新数组。
第一个数组是float*
,第二个数组也必须是float*
。
我的代码
这是我的代码,它似乎在二进制文件中打印了正确的矩阵,但是当我用 fread
读取它并将它保存到一个新数组中时,当我打印新数组时它只打印 0.0 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++;
}
P.S。我知道我必须检查 fread ecc 的所有 return 值...我稍后会做
期望输出
假设n = 4
,最终输出矩阵必须是:
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
在二进制文件中是这样的:
? ? �? �?
? �? �? @
�? �? @ @
�? @ @ @@
而且我认为没关系,它必须像这样从 .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,对文件中元素之间的 space 进行标记化 space。
使用二进制文件时,经验法则是从文件读取的代码和写入文件的代码应该相同,但功能相反。
我的意思是,在你的情况下,你有一个简单的循环,将 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;
}
}
严格来说,您不需要 x
中间变量来进行读取或写入,但我将其保留在那里以保持代码相同且更易于理解。