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

后端 未结 1 1317
攒了一身酷
攒了一身酷 2021-01-29 00:20

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 file

相关标签:
1条回答
  • 2021-01-29 00:33

    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.

    0 讨论(0)
提交回复
热议问题