2013-04-01 290 views
3

寫所以,我有其中包含一個input.bin文件以下二進制文件讀取/用C

IK-SZH;jdl72u;John Doe;2013-03-28 11:05 
IK-GRR;kat91n;Jane Doe;2013-03-21 15:41 
IK-GRR;oat62f;Jane Doe;2013-03-24 08:08 

什麼我做的是把它讀成一個結構。用數據做一些事情。添加/刪除線條。 然後我想用上述相同的格式將結構的內容寫回到input.bin文件中。

但不是像上面那樣出現。是這樣的(無空格):

IK-SZH NUL jdl72u NUL John Doe NUL NUL NUL NUL NUL 2013-03-28 NUL NUL NUL IK-GRR NUL kat91n NUL Jane Doe NUL NUL NUL NUL ... 

當我重新讀取文件(與完全無效),只把1號線到結構

我的代碼

typedef struct foo { 
    char kid[7];  
    char jid[7];  
    char name[21]; 
    char time[20]; 

} Foo; 

Foo foo[200]; 
FILE* fp; 
int size; 

- ------文件閱讀器

void read(char* filename){ 
    fp = fopen(filename, "rb"); 
    int i = 0; 

    while (!feof(fp)) { 

     if (fp==NULL){perror("File opening error\n"); exit(1);} 

     fscanf(fp,"%[^;]; %[^;]; %20[^\;]; %s\n", foo[i].kid, foo[i].jid, 
       foo[i].name, foo[i].time); 
     i++; 
    } 

    size = i; 

    print(); 

    fclose(fp); 
} 


void print(){ 
    int i; 
    for (i = 0; i < size; ++i){ 
     printf("%s\t %s\t %s\t %s\n", foo[i].kid, foo[i].jid, 
       foo[i].name, foo[i].time); 
    } 
} 

-----作家

void write(){ 
    char str[1000]; 

    FILE* f = fopen("input.bin", "wb"); 
    fseek(f, 0, SEEK_SET); 
    int i; 
    for (i = 0; i < jel_size; i++) 
      fwrite(&foo[i], sizeof(struct foo), 1, f); 
    fclose(f); 

} 

想這一點,但是這並沒有寫入任何文件:

char str[1000]; 
    sprintf(str,"%s;%s;%s;%s\n", jelent[i].kazon, 
        jelent[i].jazon,jelent[i].nev, jelent[i].ido); 

     write(f,&str,sizeof(str))!=sizeof(str); 
+6

的input.bin在我看來,一個文本文件,而不是二進制文件。 –

+1

您可能要()考慮使用fprintf(),而不是FWRITE或write()。 –

+0

你應該在文本模式下打開一個文本文件,而不是二進制模式。 –

回答

5

你的結構定義是:

typedef struct foo 
{ 
    char kid[7];  
    char jid[7];  
    char name[21]; 
    char time[20]; 
} Foo; 

寫入結構的文件中的代碼是在write()

for (i = 0; i < jel_size; i++) 
    fwrite(&foo[i], sizeof(struct foo), 1, f); 

如果結構與所有字節零intialized,則第一數據行你提到:

IK-SZH;jdl72u;John Doe;2013-03-28 11:05 

我們可以推斷是t他結構包含:

IK-SZH\0 
jdl72u\0 
John Doe\0\0\0\0\0\0\0\0\0\0\0\0\0 
2013-03-28 11:05\0\0\0\0 

這或多或少同意你說的話的文件包含:

IK-SZH NUL jdl72u NUL John Doe NUL NUL NUL NUL NUL 2013-03-28 NUL NUL NUL 

據我估計,你缺少的名稱和時間,一個經過幾次完全無效NUL日期之後。

如果你想文本輸出,你將不得不使用fprintf()類似於您在read()功能有fscanf()聲明write()中的數據格式。你應該從函數返回一個狀態來表明它是否成功。你可以爭取檢查fclose()也是成功的。

void write(void) 
{ 
    FILE *fp = fopen("input.bin", "w"); 
    if (fp != 0) 
    { 
     for (int i = 0; i < jel_size; i++) 
      fprintf(fp, "%s;%s;%s;%s\n", foo[i].kid, foo[i].jid, foo[i].name, foo[i].time); 
     fclose(fp); 
    } 
} 

如果你想二進制輸出,你應該使用read()二進制輸入。再次,你應該考慮返回成功或失敗的跡象;避免全局變量也是很好的。

void read(const char *filename) 
{ 
    FILE *fp = fopen(filename, "rb"); 
    if (fp != 0) 
    { 
     for (i = 0; fread(&foo[i], sizeof(foo[i]), 1, fp) == 1; i++) 
      ; 
     fclose(fp); 
     size = i; 
    } 
} 

兩種技術都可以工作;試圖在輸出上使用一個,而在輸入上使用另一個則會導致混亂和混亂。

注意,功能read()write()使用由POSIX與不同的接口。當你堅持使用標準的C,名字是公平供您使用,但您可能會與其他名稱,如reader()writer()foo_read()foo_write()更好。

+0

不敢相信我沒有想過fprintf。 我已經知道了fread,fwrite的東西。只是不想使用,因爲有;文件中的分隔符,並不確定如何解決這個問題。 非常感謝您的幫助! – Vaner