简体   繁体   中英

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM