【问题标题】:Function for loading data from binary files to array of structs用于将数据从二进制文件加载到结构数组的函数
【发布时间】:2018-06-08 07:50:34
【问题描述】:

这是我的代码,用于将数据从二进制文件加载到结构数组,但我收到找不到文件的错误。文件在那里,它可以与其他功能一起使用。

void ispis2(void) {
    float data_num = brojanje();
    int N = data_num / 3;
    ARTIKL artikl[120];
    FILE *fp = NULL;
    fp = fopen("artikli.bin", "rb");
    if (fp == NULL) {
        fprintf(stderr, "Pogreska: %s\n", strerror(errno));
    }
    else {
        for (int i = 0; i < N; i++) {
            fread(&artikl[i].ime, sizeof(artikl), 1, fp);
            fread(&artikl[i].cijena, sizeof(artikl), 1, fp);
            fread(&artikl[i].ID, sizeof(artikl), 1, fp);
        }

        for (int i = 0; i < N; i++) {
            printf("Ime: %s", artikl[i].ime);
            printf("Cijena: %f", artikl[i].cijena);
            printf("ID: %d", artikl[i].ID);

        }
    }
}

【问题讨论】:

  • 该文件不在您认为的位置,请检查您的程序运行的位置。告诉我们更多关于您的平台/IDE/编译器等的信息。
  • 仔细检查文件名并根据需要使用完整路径。
  • This:fread(&amp;artikl[i].ime, sizeof(artikl), 1, fp); 看起来很可疑,因为它基本上是在说单个字段 ime 与整个 120 个 ARTIKLs 数组的大小相同。这没有任何意义,因为该字段位于该数组的一个元素中。你的意思可能是sizeof artikl[i].ime
  • 您的问题应该有一些minimal reproducible example 并且不是一个,因为我们不知道ARTIKL 是什么
  • 我正在使用 sam 文件来写入二进制文件并完美运行。 ARTIKL 是一个结构。我将 fread 调整为 sizeof artikl[i].ime 还是不行。

标签: c


【解决方案1】:

你可能没有在你想要的环境中运行你的程序(特别是检查当前的working directory)。

当然你的fread-s 闻起来很臭。再次阅读standard C input/output 函数的文档,尤其是freadsizeof(artikl) 参数肯定是错误的(但由于您的问题没有解释 ARTIKL 的真正含义,我们无法提供更多帮助)。

directory 的概念在 C11 标准 n1570 中是未知的。另见this。但如果您使用的是 POSIX 系统,则可以使用 getcwd(3) 查询它。其他操作系统有不同的查询方式(例如 Windows 上的GetCurrentDirectory)。阅读Operating Systems: Three Easy Pieces 了解更多关于操作系统的信息,同时阅读一本不错的 C 编程书籍。

所以你也许可以改进错误处理:

if (fp == NULL) {
    fprintf(stderr, "Pogreska: %s\n", strerror(errno));
    char wdbuf[128];
    memset(wdbuf, 0, sizeof(cwdbuf));
    fprintf(stderr, "working directory: %s\n", 
            getcwd(wdbuf, sizeof(wdbuf));
}

(上面的代码不处理getcwd的失败;一个健壮的程序应该处理)

顺便说一句,我不确定像您这样处理二进制文件是否值得(二进制格式非常脆弱,您需要非常精确地记录其格式;请记住,大多数时候,数据比处理它的应用程序更有价值)。您可能会考虑以某种文本格式(如JSONYAML、....)或某些sqlite 数据库中存储数据。考虑使用适当的库(例如,jansson 用于 JSON,libsqlitefor sqlite)

不要忘记编译带有所有警告和调试信息的代码(所以gcc -Wall -Wextra -gGCC)。阅读你的编译器的文档(例如如何invoke it)和你的debugger。使用调试器了解程序的行为。

【讨论】:

  • 这是学校的项目,我正在尝试制作收银机。我今天需要完成它,所以如果您能以任何方式提供帮助,我将不胜感激。我正在使用 Visual Studio 2017,该二进制文件类似于存储中所有项目的数据库。
  • 今天你不会这样做。你来晚了,还有一些C编程的基本概念你还是不明白。对此我很抱歉,但我们真的无能为力!对于您的下一个学校项目,请投入更多时间和精力。顺便说一句,StackOverflow 不是 do-my-homework 网站
  • 我今天需要一些收银程序。你至少有一个简单版本的想法吗?
  • 不,你相信我会做你的功课。但我不会。我可能比你父亲大,而且我确实在大学教过书,所以我理解学生自己编写程序的重要性。见norvig.com/21-days.html;下一次,加倍努力!
  • 那我的回答应该够了。当然,你需要花几天时间阅读一些不错的 C 编程书籍,并阅读你正在使用的每个函数的文档
猜你喜欢
  • 2014-01-27
  • 2021-06-28
  • 2011-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多