2017-06-12 104 views
1

我想创建一个合成数据集(0-1之间的值)并将它们保存在二进制文件中。下面是我的代码:写入和读取二进制文件时发生的问题

int n = 4000, dim = 4,i,j; 
FILE *fp=fopen("dataset.data", "w+"); 
double *data = (double *) calloc(n * dim, sizeof(double)); 
double *data_to_read = (double *) calloc(n * dim, sizeof(double)); 

// Generate dataset 
srand(1); 
for (i = 0; i < (n * dim); ++i) { 
    data[i] = (float) rand()/(float) RAND_MAX; 
} 

// Writing to binary file 
if (fp) fwrite(data, 1, (n*dim) * sizeof(double), fp); 
else { printf("Something went wrong while writing to File !! \n"); } 

// To make sure data have been written, read and print out the file. 
fp = fopen("Home/dataset.data", "rb"); 
fread(data_to_read, 1, (n*dim) * sizeof(double), fp); 
fclose(fp); 

for (i = 0; i < n; ++i) { 
    printf("[%d] ", i); 
    for (j = 0; j < dim; ++j) { 
     printf("%f, ", data_to_read[i * dim + j]); 
    } 
    printf("\n"); 
} 

不过,我在这让我觉得有什么不对的印刷结束得到了很多零。类似这样的:

[3962] 0.519062, 0.877532, 0.686047, 0.396526, 
[3963] 0.419497, 0.494090, 0.163209, 0.061352, 
[3964] 0.144232, 0.113827, 0.082452, 0.777153, 
[3965] 0.609784, 0.647998, 0.902744, 0.414265, 
[3966] 0.543551, 0.462175, 0.775620, 0.842364, 
[3967] 0.607382, 0.274029, 0.599672, 0.682604, 
[3968] 0.000000, 0.000000, 0.000000, 0.000000, 
[3969] 0.000000, 0.000000, 0.000000, 0.000000, 
[3970] 0.000000, 0.000000, 0.000000, 0.000000, 
[3971] 0.000000, 0.000000, 0.000000, 0.000000, 
[3972] 0.000000, 0.000000, 0.000000, 0.000000, 
[3973] 0.000000, 0.000000, 0.000000, 0.000000, 
[3974] 0.000000, 0.000000, 0.000000, 0.000000, 
[3975] 0.000000, 0.000000, 0.000000, 0.000000, 
[3976] 0.000000, 0.000000, 0.000000, 0.000000, 
[3977] 0.000000, 0.000000, 0.000000, 0.000000, 
[3978] 0.000000, 0.000000, 0.000000, 0.000000, 
[3979] 0.000000, 0.000000, 0.000000, 0.000000, 
[3980] 0.000000, 0.000000, 0.000000, 0.000000, 
[3981] 0.000000, 0.000000, 0.000000, 0.000000, 
[3982] 0.000000, 0.000000, 0.000000, 0.000000, 
[3983] 0.000000, 0.000000, 0.000000, 0.000000, 
[3984] 0.000000, 0.000000, 0.000000, 0.000000, 
[3985] 0.000000, 0.000000, 0.000000, 0.000000, 
[3986] 0.000000, 0.000000, 0.000000, 0.000000, 
[3987] 0.000000, 0.000000, 0.000000, 0.000000, 
[3988] 0.000000, 0.000000, 0.000000, 0.000000, 
[3989] 0.000000, 0.000000, 0.000000, 0.000000, 
[3990] 0.000000, 0.000000, 0.000000, 0.000000, 
[3991] 0.000000, 0.000000, 0.000000, 0.000000, 
[3992] 0.000000, 0.000000, 0.000000, 0.000000, 
[3993] 0.000000, 0.000000, 0.000000, 0.000000, 
[3994] 0.000000, 0.000000, 0.000000, 0.000000, 
[3995] 0.000000, 0.000000, 0.000000, 0.000000, 
[3996] 0.000000, 0.000000, 0.000000, 0.000000, 
[3997] 0.000000, 0.000000, 0.000000, 0.000000, 
[3998] 0.000000, 0.000000, 0.000000, 0.000000, 
[3999] 0.000000, 0.000000, 0.000000, 0.000000, 

我不知道我的写作方式是否正确。任何帮助都已被证实。

+2

只要您每次调用函数,都要检查'fopen()'的返回值。此外,你打开你忘记关闭的文件。你应该在'fp = fopen(“Home/dataset.data”,“rb”)之前'fclose(fp)';' – Badda

+0

另外,检查fwrite/fread的返回值。 – Neil

+0

@Badda你是对的。 fopen的定位是问题。它现在已经修复。如果您在阅读时使用二进制模式('b'),则表示感谢 – Medo

回答

0

我想我已经发现了你的问题:

你写这个文件:

FILE *fp=fopen("dataset.data", "w+"); 

但是看了你的这个文件:

fp = fopen("Home/dataset.data", "rb"); 

你是不是读你的文件在写。

+0

没有,我修好了路径,但仍然是同样的问题。感谢您的检查。 – Medo

2

有在你的代码的几个问题:

  • 你是不是fclose荷兰国际集团的文件,一旦你已经写入。
  • 如果成功,您不检查所有fopen
  • 您需要使用“wb”而不是“w +”打开文件。
  • 您没有读取与您写入相同的文件。
  • 如果该文件无法打开写入,您显示错误消息,但你还是继续尝试从文件中读取您无法打开

修正程序(包括毫无意义的意见和怀疑修正错误消息),与<<评论都是我

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
    int n = 4000, dim = 4, i, j; 
    FILE *fp = fopen("dataset.data", "wb");     // << wee need "wb" here 
    double *data = calloc(n * dim, sizeof(double));   // << no casts in C 
    double *data_to_read = calloc(n * dim, sizeof(double)); 

    // Generate dataset 
    srand(1); 
    for (i = 0; i < (n * dim); ++i) { 
    data[i] = (float)rand()/(float)RAND_MAX; 
    } 

    // Writing to binary file 
    if (fp) 
    fwrite(data, 1, (n*dim) * sizeof(double), fp); 
    else 
    { 
    printf("Something went wrong while opening the file to write !! \n"); 
    return 1;      // << abort of file could not be opened 
    } 

    fclose(fp);      // << closing file 

    // Read and print out the file. 
    fp = fopen("dataset.data", "rb"); // << opening the same file than the one we wrote to 

    if (fp)       // << checking if file could be opened 
    { 
    fread(data_to_read, 1, (n*dim) * sizeof(double), fp); 
    fclose(fp); 

    for (i = 0; i < n; ++i) { 
     printf("[%d] ", i); 
     for (j = 0; j < dim; ++j) { 
     printf("%f, ", data_to_read[i * dim + j]); 
     } 
     printf("\n"); 
    } 
    } 
    else 
    { 
    printf("Something went wrong while opening the file to read!! \n"); 
    return 1; 
    } 

    // << check if read data is equal to written data 

    if (memcmp(data_to_read, data, n*dim) == 0) 
    { 
    printf("\nRead data is equal to written data\n"); 
    } 

    return 0; 
} 

免责声明:可能有其他错误,我没有注意到。

+0

'printf(“\ nRead data is equal to written data \ n”);' - >'puts()'因为你没有格式化任何东西。另外我也不明白为什么你和很多其他人在'for'循环之外声明'i'并且投出了'malloc'的返回值。最好避免在C中做这些事情? – Badda

+1

@Badda只是因为我坚持OP的代码,但是我会删除演员。 'puts'和'printf':put'puts'是毫无意义的,因为今天的优化编译器通常会处理这个问题,并且增益很小,因为底层I/O比使用'puts'而不是'printf '.. –

0

打开这样的文件:

FILE *fp = fopen("dataset.data", "wb+"); 

然后,FWRITE数据写入后,关闭文件指针或复位:

fclose(fp); 
//alternatively: 
// fflush(fp); 
// fseek(fp, 0, SEEK_SET); 

最后,校正第二FOPEN的路径