【问题标题】:C i cant read binary file properlyC 我无法正确读取二进制文件
【发布时间】:2017-10-18 14:33:37
【问题描述】:

您好,我有一个包含几个变量的结构,我尝试从/向二进制文件写入和读取它们,但是当我读取它们时,我只看到奇怪的符号而且我不知道我搞砸了什么,我尝试了几个变体但它们都不起作用

    typedef struct catalog
    {
        char num[20];
        char name[80];
        char author[50];
        double price;
        int year;
        char publisher[80];
    } Catalog;

    Catalog* createCatalogData()
    {
        Catalog* c = malloc(sizeof(*c));
        if (!c)
        {
            // Ups... add error handling
            exit(0);
        }

        printf("Add num ");
        getString(&c->num);

        printf("Add name ");
        getString(&c->name);

        printf("add author ");
        getString(&c->author);

        printf("Add price ");
        if (scanf("%lf", &c->price) != 1)
        {
            // Ups... add error handling
            exit(0);
        }

        printf("Add publisher");
        getString(&c->publisher);

        printf("Add year");
        if (scanf("%d", &c->year) != 1)
        {
            // Ups... add error handling
            exit(0);
        }

        char *filePath = malloc(strlen(c->num) + 13);
        char *folderName = "Catalogs\\";
        strcpy(filePath, folderName);
        strcat(filePath, c->num);
        strcat(filePath, ".bin");

        FILE *file = fopen(filePath, "wb");
        if (file == NULL)
        {
            printf("Error opening file!\n");
            exit(1);
        }


        fwrite(&c->num,1, strlen(c->num), file);
        fwrite(&c->name,1, strlen(c->name), file);
        fwrite(&c->author,1, strlen(c->author), file);
        fwrite(&c->price, 1, sizeof(double), file);
        fwrite(&c->publisher,1, strlen(c->publisher), file);
        fwrite(&c->year,1, sizeof(int), file);

        fclose(file);

        return c;
    }

    Catalog* readCatalogData(char *filePath)
    {
        Catalog* c = malloc(sizeof(*c));


        FILE* fh;
        fopen_s(&fh, filePath, "rb");
        //check if file exists


        char *ptr;
        //read line by line
        const size_t line_size = 300;
        char* line = malloc(line_size);
        int counter = 0;
        char* date;

        fread(c->num, 1, 21, fh);
        fread(c->name, 1, 80, fh);
        fread(c->author, 1, 50, fh);
        fread(&c->price, 1, sizeof(double), fh);
        fread(c->publisher, 1, 80, fh);
        fread(c->year, 1, sizeof(int), fh);

        return c;
    }

【问题讨论】:

  • 写作时不要在&c->num等中使用&
  • 我已经改变了它,但仍然无法正常工作,但如果价格没有 &
  • malloc(strlen(c->num) + 13) off-by-one 错误。
  • 我强烈建议您阅读指针以及如何/何时将数组视为指针。
  • 你考虑过使用JSON吗?你不会有二进制(但文本)文件,你可以很容易地找到好的库来解析它们。

标签: c file io binary


【解决方案1】:

当你这样做时,例如

fwrite(&c->num,1, strlen(c->num), file);

您写入的字节数不定,没有任何终止符。当您读取文件时,您不知道实际读取了多少字节。

上面的fwrite 调用实际上包含另一个 错误,因为你写了一个指针 而不是c->num 中的实际数据。

与其一一编写数据成员,不如在一次调用中编写整个结构:

fwrite(c, sizeof c, 1, file);

当读取文件时,在单个 fread 调用中读取整个结构。


重要说明(正如 Attie 在评论中指出的那样):如果您打算使其可移植,那么您应该使用 serialization 来读取和写入数据,因为结构的大小可能不一样所有平台。

对于简单的代码,只是“实验”,那么它就可以正常工作。

【讨论】:

  • @HristoVutov 那么你做错了什么。写/读整个结构应该可以正常工作。
  • 只有当您 100% 确定打包不会因构建而发生变化并且您 100% 确定文件不会被访问时,才可以将结构写入磁盘在另一个架构上。简而言之。不要这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
  • 2019-09-24
  • 1970-01-01
相关资源
最近更新 更多