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

时间:2012-03-23 10:21:29

标签: c struct fread

让我的程序读取文件中的数据时遇到了一些麻烦。问题是该文件当前是空的。每次运行程序时,都会填充单个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);
}

6 个答案:

答案 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中使用它会使应用程序崩溃。