2017-06-12 101 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的路徑