让我的程序读取文件中的数据时遇到了一些麻烦。问题是该文件当前是空的。每次运行程序时,都会填充单个books []数组,并在代码中稍后写入该文件。虽然我确信当文件中的所有10个结构都存在时它会起作用,但是由于文件是空的并且它正在尝试读取10个结构,所以它崩溃了。
有没有办法从文件中读取未知数量的结构(最多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 :(得分:2)
是的,你可以这样做:
fopen
返回的值,以确保文件存在size_t
fread
值
答案 1 :(得分: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 :(得分:1)
崩溃?我希望,不是那些陈述,除非文件根本不存在。如果您假设阵列中有10个有效项,则可能会崩溃,因为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;
}
答案 3 :(得分:0)
代码看起来很好(虽然没有试一试)。请参阅fread手册页 - 它返回读取的项目数。
答案 4 :(得分: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);
}
答案 5 :(得分:0)
我不确定,但fread()
不应该崩溃,而是返回读取的项目数,在这种情况下为0。另外,我并不完全理解stock books[10];
行是如何编译的,它应该是struct stock books[10];
。
我建议两件事:
1.替换为struct stock books[10];
2.要做的一件重要事情是检查fptr是否为NULL。也许它无法打开文件(可能不在同一目录中或者还不存在),这会导致NULL fptr,并且在fread中使用它会使应用程序崩溃。