Can i use fscanf with binary files in the c language?

孤人 提交于 2019-12-25 03:15:29

问题


So i had an exam, and one of the excercies included to scan names from a binary file. I had used fscanf(), but my prof told me that i cant use fscanf in binary files. but why? my program works just fine even if i do so.


回答1:


I admit that I didn't find a way to explain what is wrong with fscanf() and binary files that would be understood easily, but here is an example of how the binary file generated is read erroneously by fscanf()

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Entry
{
    char text[64];
    int  age;
};

int main()
{
    FILE        *file;
    struct Entry entry;

    file = fopen("data.bin", "wb");
    if (file == NULL)
        return -1;

    entry.age = 30;

    memset(entry.text, 0, sizeof(entry.text));
    strcpy(entry.text, "Iharob Al Asimi");

    fwrite(&entry, sizeof(entry), 1, file);

    entry.age = 22;

    memset(entry.text, 0, sizeof(entry.text));
    strcpy(entry.text, "Claudio Urdaneta");

    fwrite(&entry, sizeof(entry), 1, file);

    entry.age = 29;

    memset(entry.text, 0, sizeof(entry.text));
    strcpy(entry.text, "Dayana Orozco");

    fwrite(&entry, sizeof(entry), 1, file);
    fclose(file);

    file = fopen("data.bin", "rb");
    if (file == NULL)
        return -1;
    fprintf(stderr, "with fscanf()\n");
    /* this is intentionally == 1 to prove the point */
    while (fscanf(file, "%63s%d", entry.text, &entry.age) == 1)
        fprintf(stderr, "\t%s, %d\n", entry.text, entry.age);

    rewind(file);

    fprintf(stderr, "with fscanf()\n");
    while (fread(&entry, sizeof(entry), 1, file) == 1)
        fprintf(stderr, "\t%s, %d\n", entry.text, entry.age);

    fclose(file);

    return 0;
}

The problem is that fscanf() will scan for text and match against the specifiers you pass to it.

But a binary file is just a bunch of bytes stored with a given structure, in the example above we write 64 + sizeof(int) bytes per record, one of the items is just text so reading bytes with fscanf() works as expected and it of course stops at the whitespace character.

But then the number has no text represantation in the file, and hence you cannot read it with fscanf().

Also, please note this

while (fscanf(file, "%63s%d", entry.text, &entry.age) == 1)

the correct way of doing it is

while (fscanf(file, "%63s%d", entry.text, &entry.age) == 2)

but then nothing will be printed because the integer wont be matched.

So when working with binary files you need

  • fread()/fwrite()

whereas when the data is just text

  • fprintf()/fscanf()

will be good.



来源:https://stackoverflow.com/questions/28506570/can-i-use-fscanf-with-binary-files-in-the-c-language

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!