【问题标题】:Reading an integer and then 3 structures from a binary file in C从 C 中的二进制文件中读取一个整数,然后读取 3 个结构
【发布时间】:2020-07-01 18:49:40
【问题描述】:

我想读取我编写的 .bin 文件。我在 .bin 文件中写了一个整数和 3 个结构。当我尝试从中读取时,出现错误:

Run-Time Check Failure #2 - Stack around the variable 'A' was corrupted. occurred

这是我的结构:

typedef struct videoteka {
char naslov[50];
char glumac[50];
char vrsta[40];
long int rBroj;
}FILM;

这是我写入 .bin 文件的方式:已修复并再次写入文件

int main()
{
FILM* film = malloc(3 * sizeof(*film));
strcpy(film[0].naslov, "Nana");
strcpy(film[0].glumac, "Goran");
strcpy(film[0].vrsta, "Komedija");
film[0].rBroj = 123456;
strcpy(film[1].naslov, "Blabla");
strcpy(film[1].glumac, "Mirko");
strcpy(film[1].vrsta, "Horor");
film[1].rBroj = 6467347;
strcpy(film[2].naslov, "Tanana");
strcpy(film[2].glumac, "Ivan");
strcpy(film[2].vrsta, "Drama");
film[2].rBroj = 8421841;

FILE* fPt = fopen("filmovi.bin", "wb");
int n = 3;
fwrite(&n, sizeof(int), 1, fPt);
fwrite(&film, sizeof(FILM), 3, fPt);
fclose(fPt);
return 0;
}

这就是我试图从中读取的方式:

FILM* ucitavanjeFilmova(char fileName[20], int n)
{
FILM *(A[3]);
for (int i = 0; i < 3; i++)
    A[i] = (FILM*)malloc(sizeof(FILM));
FILE* fPt = fopen(fileName, "rb");
fseek(fPt, 5, SEEK_SET);
fread(&A, sizeof(FILM), 3, fPt);
fclose(fPt);
return A;
}

我首先尝试为 FILM 类型的 n(在本例中为 3)结构分配内存。然后我尝试读取 3 个结构并将它们存储到指针 A 的地址。之后我返回指针 A。我正在使用 fseek,因为在所有结构之前将一个整数写入文件。

【问题讨论】:

  • 一方面,FILM *(film[3]); 应该是FILM *film[3]; 用于读取过程的数组无论如何都与用于输出的数组不匹配。读取时,三个malloc都写入同一个变量A
  • 这是否意味着我的 .bin 文件甚至没有被正确写入? .bin 文件不是用我要问的这个程序代码编写的。它是写在我上面发布的第一个代码块上的。有没有可能它一开始就没有将结构正确地写入 .bin 文件?将 A 更正为 A[i],仍然给我同样的错误..
  • @WeatherVane 的区别?
  • 我建议在这种只有 3 条记录的情况下(建议!),您可以使用文件转储制表符检查输出文件。
  • 在我看来你正在写指向文件的指针......不好

标签: c struct integer binaryfiles fread


【解决方案1】:

当你调用fwrite 时,你需要传递一个指向你想要写的东西的指针。但你不要那样做。你将一个指向FILM的指针传递给它,它是一个指针数组,绝对不是你想要写入文件的东西!

由于需要将三个不同的内存块写入文件,因此需要调用fwrite 三次。每次,传递一个指向单个 FILM 对象的指针。

同样,您的 fread 会覆盖指向您分配的内存的指针。您需要调用fread 三次,每次都向它传递一个指向您分配的块之一的指针。

【讨论】:

    【解决方案2】:

    你的主要问题从这里开始:

    fwrite(&(film[3]), sizeof(FILM), 3, fPt);
    

    对不起..但那都是错的。

    看这里:

    FILM *(film[3]);
    

    那么film 是什么?这是一个由 3 个指向 FILM 的指针组成的数组。所以即使访问film[3] 也是错误的。您可以访问film[0]film[1]film[2]film[3]!没有。

    事实是,您不想要一个包含 3 个指向 FILM 的指针的数组 - 您希望在一个数组中包含 3 个 FILM

    所以简单地做:

    FILM film[3];
    

    忘记 malloc 的东西

    然后你的写作就开始了:

    fwrite(film, sizeof(FILM), 3, fPt);  
    

    编辑

    这里的语法似乎有些混乱。所以:

    FILM *(film[3]);
    FILM *film[3];
    FILM* film[3];
    

    相同语句。它们都是:film 是一个由 3 个指向 FILM 的指针组成的数组。

    不是你想要的。

    你想要的是 - 以简单的形式:

    FILM film[3];
    ...
    fwrite(film, sizeof *film, 3, fPt);
    

    如果您想要malloc,您可以通过多种方式进行操作。简单的方法是:

    FILM *film = malloc(3 * sizeof *film);
    

    比较“特别”的方式是

    FILM (film*)[3] = malloc(sizeof *film);
    ...
    fwrite(film, sizeof *film, 1, fPt);
    

    对于语法部分:

    FILM (film*)[3]
    

    表示指向包含 3 个 FILM 的数组的指针

    【讨论】:

    • @PatrikMakaj Nope FILM *(film[3]);FILM *film[3]; 相同,而这不是您想要的。如果你想处理指针和malloc,你需要FILM (*film)[3],但同样——不是你想要的——要复杂得多。
    • 我需要将它用作指针,因为我在一个函数中使用它,该函数返回我需要在程序中进一步使用的这 3 个结构的地址。所以我不能忘记 malloc 的东西,因为它不能是本地结构。
    • 我认为FILM*(film[3]); 工作得很好,因为它是一个指向结构数组的指针。而且我不确定我是否使用&amp;(film[3]),是否使用第一个结构的地址并将一个 3*sizeof(FILM) 的块(以字节为单位)写入文件。
    • @PatrikMakaj 不! FILM*(film[3]); 不是指向结构数组的指针。如果你想要,那么FILM (*film)[3] 是一个指向具有三个元素的结构数组的指针
    • 你能帮我重写代码以便整数和 3 个结构正确写入 .bin 文件吗?我不知道如何自己做。无论如何,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多