简体   繁体   English

我可以将fscanf与C语言的二进制文件一起使用吗?

[英]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. 我曾经使用过fscanf() ,但是我的教授告诉我,我不能在二进制文件中使用fscanf。 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() 我承认我没有找到一种方法来解释容易理解的fscanf()和二进制文件的问题,但这是fscanf()错误读取生成的binary文件的示例

#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. 问题在于fscanf()将扫描文本并与您传递给它的指定符匹配。

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. 但是二进制文件只是用给定结构存储的一堆字节,在上面的示例中,每条记录写入64 + sizeof(int)个字节,其中一项只是文本,因此使用fscanf()读取字节可以按预期工作,它当然会停在空白字符处。

But then the number has no text represantation in the file, and hence you cannot read it with fscanf() . 但是,该数字在文件中没有文本表示,因此您无法使用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() fread() / fwrite()

whereas when the data is just text 而当数据只是文本时

  • fprintf() / fscanf() fprintf() / fscanf()

will be good. 会变好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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