2017-04-11 117 views
0

我寫了一個程序使用fwrite的和正確的方法使用fread

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

int main(void) 
{ 
    FILE *fp; 
    int r; 
    char arr[] = "this is the string"; 
    char str[20] = {'\0'}; 

    fp = fopen("fwrite.txt", "w"); 
    fwrite(arr, 1, sizeof(arr), fp); 
    fseek(fp, SEEK_SET, 0); 
    r = fread(str, 1, sizeof(arr), fp); 

    if(r == sizeof(arr)) 
     printf("read successfully\n"); 
    else 
    { 
     printf("read unsuccessfull\n"); 
     exit(1); 
    } 

    printf("read = %d\n", r); 
    printf("%s\n", str); 

    fclose(fp); 
    return 0; 
} 

我想以這種方式來讀,但我不能這樣做。這裏有什麼問題,是我應該把&str[i]併爲fread運行一個循環,否則fread能夠將數據放入str

我越來越垃圾,我不明白爲什麼?

+2

您需要'fseek(fp,0L,SEEK_SET)'。偏移量來自哪個('SEEK_SET')之前。 –

+1

我猜你正在使用www.tutorialspoint.com作爲參考,由於某些原因,他們以錯誤的順序使用fseek,fread和fwrite參數。 – Dunno

+2

你也需要在'w + b'模式下打開 –

回答

3

主要問題是您有反向參數fseek() - 您需要在此之前的偏移量(0)(SEEK_SET)。第二個問題是您嘗試從僅用於寫入的文件中讀取文件。在這種情況下的一個更小的問題,但一個非常重要的問題是,你不會錯誤地檢查fopen()調用。 (這個fopen()相對不太可能會失敗,但更有趣的事情已經知道了。)您還應該檢查fwrite()電話(當然,您已經檢查了fread())。

修復所有這些可能會導致:

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

int main(void) 
{ 
    int rc = EXIT_SUCCESS; 
    int r; 
    const char file[] = "fwrite.txt"; 
    char arr[] = "this is the string"; 
    char str[20] = {'\0'}; 
    FILE *fp = fopen(file, "w+b"); 
    if (fp == 0) 
    { 
     fprintf(stderr, "Failed to open file %s for reading and writing\n", file); 
     rc = EXIT_FAILURE; 
    } 
    else 
    { 
     if (fwrite(arr, 1, sizeof(arr), fp) != sizeof(arr)) 
     { 
      fprintf(stderr, "Failed to write to file %s\n", file); 
      rc = EXIT_FAILURE; 
     } 
     else 
     { 
      fseek(fp, 0, SEEK_SET); 
      r = fread(str, 1, sizeof(arr), fp); 
      if (r == sizeof(arr)) 
      { 
       printf("read successful\n"); 
       printf("read = %d bytes\n", r); 
       printf("read data [%s]\n", str); 
      } 
      else 
      { 
       printf("read unsuccessful\n"); 
       rc = EXIT_FAILURE; 
      } 
     } 
     fclose(fp); 
    } 
    return rc; 
} 

實例運行:

$ ./fi37 
read successful 
read = 19 bytes 
read data [this is the string] 
$ 

注意,因爲你在輸出字符串的結尾的文件寫入空字節,這一工作在部分,然後再讀入。如果文件包含空字節,則該文件不是真正的文本文件。在Unix系統中,在二進制文件和文本文件之間沒有區別的情況下,"w+b"模式中的b並不是真的需要。如果您要將空字節寫入Windows上的文件,則應使用b來指示二進制模式。

如果您選擇了,可以通過在main()函數中沒有一個return來減少「粗糙」(或嵌套深度)。您可以使用return EXIT_FAILURE;並避免使用else和另一組大括號。顯示的代碼仔細關閉文件,如果它被打開。在通用功能中,這很重要。在main()中,由於退出過程將刷新並關閉打開的文件,所以它並不重要。

+0

是的問題是fseek參數和w + b,我使用ubuntu,如果我刪除w + b到w,它將無法工作。 – acidlategamer

+1

是;用'「w」'表示只寫。使用'「w +」'表示讀寫並在做其他事情之前清空文件。 –

+0

不檢查'fopen'的返回值不是一個小問題,imo,這是非常重要的。忽略庫函數的返回值會使調試非常非常痛苦。我甚至在文檔中提出了有關此問題的文章:http://stackoverflow.com/documentation/c/2006/common-pitfalls/15692/ignoring-return-values-of-library-functions#t=20170411151208958515 無論如何,+1提及這個 – Dunno

0

對於fopen,您無法使用"w"模式讀取文件,請改爲使用"w+"

"r" - 打開文件進行閱讀。該文件必須存在。

"w" - 創建一個空文件用於書寫。如果已存在同名文件 ,則其的內容將被刪除,並將該文件視爲新的空文件。

"a" - 附加到文件。寫入操作,在 文件末尾追加數據。如果該文件不存在,則會創建該文件。

"r+" - 打開文件以更新讀取和寫入。該文件必須存在。

"w+" - 爲讀取和寫入創建一個空文件。

"a+" - 打開文件進行閱讀和追加。