2012-03-23 20 views
0

我有一點麻煩我的程序從文件中讀取數據。問題是該文件目前是空的。每次運行該程序時,都會填充一個單一的書籍[],並在稍後的代碼中寫入文件。雖然我確定當所有10個結構都在文件中時它會工作,但現在它正在崩潰,因爲文件是空的,它正在嘗試讀取10個結構。閱讀從文件結構的數目不詳 - Visual C

有沒有辦法在一個未知的數量從文件結構(最多10個)的閱讀?

struct stock 
{ 
    char name[31]; 
    int stock; 
}; 

int main (void) 
{ 
    stock books[10]; 

    FILE *fptr; 
    fptr = fopen("stock.dat", "rb"); 
    fread(books, sizeof(struct stock), 10, fptr); 

    fclose (fptr); 
} 
+0

它在哪裏崩潰?什麼是錯誤?這是一個令人瘋狂的幾乎完整的問題描述。 – tbert 2012-03-23 11:23:41

+0

如果你在控制文件格式(即它不是由其他人定義的),我建議使用文本格式(例如名稱,每行一個股票)而不是二進制。這意味着更多的代碼,但你只寫一次代碼;該文件將更加可用。 – 2012-03-23 12:14:51

回答

2

如果你知道文件在結構的最大可能數和可以負擔得起將它們全部在內存中:

int main (void) 
{ 
    #define MAX_BOOKS 10 
    stock books[MAX_BOOKS]; 
    size_t cnt_books = 0; 
    FILE *fptr; 
    fptr = fopen("stock.dat", "rb"); 
    cnt_books = fread(books, sizeof(struct stock), MAX_BOOKS, fptr); 
    fclose (fptr); 
    return 0; 
} 

否則循環和成批讀:

while (cnt_books = fread(books, sizeof(struct stock), MAX_BOOKS, fptr)) { 
     /* ... */ 
    } 
2

是的,你可以做到這一點:

  • 你需要檢查由fopen返回的值,以確保該文件存在
  • 您需要檢查的項目數讀 - size_tfread返回的值
1

碰撞?我希望,除非文件不存在,否則不是這些陳述。如果您假設數組中有十個有效項目,則可能會崩潰,因爲name字段可能不會是有效的C字符串。

你找出你實際上有多少閱讀的方式是:

num = fread(books, sizeof(struct stock), 10, fptr); 

雖然我寧願:

num = fread (book, sizeof(*book), sizeof(book)/sizeof(*book), fptr); 

,因爲這意味着你不必改變很多代碼類型名稱或數組大小更改的事件。

如果有可能的文件竟然不開,你需要檢查fopen返回值也是如此。完整的代碼看起來是這樣的:

#include <stdio.h> 

typedef struct { 
    char name[31]; 
    int stock; 
} tStock; 

int main (void) { 
    tStock book[10]; 
    size_t num, i; 

    FILE *fptr = fopen ("stock.dat", "rb"); 
    if (fptr == NULL) { 
     num = 0; 
    } else { 
     num = fread (book, sizeof(*book), sizeof(book)/sizeof(*book), fptr); 
     fclose (fptr); 
    } 

    printf ("Read %d items\n", num); 
    for (i = 0; i < num; i++) { 
     printf (" Item %d is %s, %d\n", book[i].name, book[i].stock); 
    } 

    return 0; 
} 
0

該代碼看起來很好(雖然沒有放棄它)。請參閱fread手冊頁 - 它返回讀取的項目數。

0
fptr = fopen("stock.dat", "rb"); 
if(fptr == NULL) 
{ 
    // error 
} 
else 
{ 
    for(int i=0; i<10 && !feof(fptr); i++) 
    { 
    fread(&books[i], sizeof(struct stock), 1, fptr); 
    } 
    fclose(fptr); 
} 
+0

我相信你的意思是1而不是10裏面的fread函數 – 2012-03-23 10:31:54

+0

@CodeChordsman的確,我的代碼完全錯了,自己也注意到了它。感謝您的糾正。 – Lundin 2012-03-23 10:33:23

0

我不知道,但fread()不應該崩潰,但返回的項目數量看,在這種情況下是0。另外我不完全明白stock books[10];這行是如何編譯的,應該是struct stock books[10];

我會建議兩件事: 1.替換爲struct stock books[10]; 2.一個重要的事情是檢查fptr不是NULL。也許它無法打開文件(可能不在同一個目錄中,或者不存在),這會導致一個NULL fptr,在fread中使用它會導致應用程序崩潰。

+0

'stock books [10];'將用C++編譯器編譯 – gbulmer 2012-03-23 15:58:11