繁体   English   中英

从文件中读取未知数量的结构-C

[英]Reading unknown number of structs from file - C

让我的程序从文件中读取数据时遇到麻烦。 问题是该文件当前为空。 每次运行该程序时,将填充单个book []数组,并稍后在代码中将其写入文件。 虽然我确定所有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);
}

是的,您可以这样做:

  • 您需要检查fopen返回的值以确保文件存在
  • 您需要检查读取项目的数量-在size_t的返回值fread

如果您知道文件中结构的最大数量,并且有能力将它们全部存储在内存中:

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)) {
      /* ... */
    }

崩溃? 我希望这些语句不行,除非文件根本不存在。 如果您假设数组中有十个有效项,则可能会崩溃,因为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;
}

该代码看起来不错(尽管没有尝试)。 请参阅fread手册页-它返回读取的项目数。

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);
}

我不确定,但是fread()不应该崩溃,而是返回读取的项目数,在这种情况下为0。 另外,我也不完全了解行stock books[10]; 编译时,应该是struct stock books[10];

我建议两件事:1.替换以struct stock books[10]; 2.重要的事情是检查fptr是否不为NULL。 可能无法打开文件(可能不在同一目录中或尚不存在),这将导致NULL fptr,并且在fread中使用它会使应用程序崩溃。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM