2012-03-23 38 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