从二进制文件读取到一个整数

3
我对二进制文件及其读取有点困惑,希望有人能帮忙解答。我有一个包含以下比特位的文件:
00000000000000000000000000000111 

(32位。我数了一下)

现在我编写了这段代码:

int main()
{
    FILE * f1;
    f1 = fopen("file2", "rb");
    int i = 0;
    fread(&i, sizeof(int), 1, f1);
    printf("%d", i);
    fclose(f1);
    return 0;

}

打印出来的是808464432,为什么不是7?谢谢阅读。


你如何检查文件的内容? - Iharob Al Asimi
2
请输出您的 sizeof(int)。你可能正在处理 2 字节的 int,这意味着你读取了两个字节的 0 位值,这意味着你的“int”将为 0。而你是如何计算这些位的呢?如果您的文件是“二进制”的,则它的文件大小为 4 字节。如果是文本,则为 32 字节。 - Marc B
3
这句话的意思是,Iharob 的猜测是正确的,该文件不包含“0000...”这些位,而是包含 0 字符(ASCII 中的 0x30),后面跟着一些 1 字符。808464432 = 0x30303030。 - mafso
1
请注意,这些文件是非便携式的(在一台机器上编写,在另一台机器上无法读取),并且对于使用不同编译器(如果它们不兼容ABI)编译的代码可能是不一致的。fwrite(&i, sizeof i, 1, f1) - mafso
我现在明白了,谢谢!那么为什么我只能从那个表单中编写二进制文件呢? - mike
显示剩余3条评论
2个回答

4
那不是二进制文件,而是文本文件,请尝试使用以下方法。
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *file;
    int   value;
    char  text[33];
    char *endptr;

    file = fopen("file2", "r");
    if (file == NULL) /* check that the file was actually opened */
        return -1;
    if (fread(text, 1, sizeof(text) - 1, f1) != sizeof(text) - 1)
    {
        fclose(file);
        return -1;
    }
    text[32] = '\0';
    value    = strtol(text, &endptr, 2);
    if (*endptr == '\0')
        printf("%d", value);
    fclose(file);
    return 0;
}

要写入二进制文件,你需要使用以下代码:
#include <stdio.h>

void hexdump(const char *const filename)
{
    FILE         *file;
    unsigned char byte;


    file = fopen(filename, "rb");
    if (file == NULL)
        return;
    fprintf(stdout, "hexdump of `%s': ", filename);
    while (fread(&byte, 1, 1, file) == 1)
        fprintf(stdout, "0x%02x ", byte);
    fprintf(stdout, "\n");
}

int main()
{
    const char *filename;
    FILE       *file;
    int         value;

    filename = "file.bin";
    file     = fopen(filename, "wb");
    if (file == NULL)
        return -1;
    value = 7;
    if (fwrite(&value, sizeof(value), 1, file) != 1)
        fprintf(stderr, "error writing to binary file\n");
    fclose(file);

    /* check that the content of the file is not printable, i.e. not text */
    hexdump(filename);

    file = fopen(filename, "rb");
    if (file == NULL)
        return -1;
    value = 0;
    if (fread(&value, sizeof(value), 1, file) != 1)
        fprintf(stderr, "error writing to binary file\n");
    else
        fprintf(stdout, "The value read was %d\n", value);
    fclose(file);

    return 0;

}

如上面的示例所示,在file.bin中存储的数据不是文本格式,您无法使用文本编辑器检查它,因为字节0x000x07是不可打印的,事实上,0x00是在C语言中用于标记字符串结尾的nul字节。


但根据这篇帖子,不是所有的文件都是二进制的,除非明确告知它们是文本?https://dev59.com/ZEfSa4cB1Zd3GeqPBfWd - mike
因为仅包含文本的二进制文件等效于相应的文本文件,但如果您在二进制文件中存储整数,则很难看到整数值的文本表示形式。此外,据我所知,“rb”不像“r”一样处理行尾字符。 - Iharob Al Asimi
谢谢您的时间,但我有点困惑。我要如何创建一个32位/4字节的二进制文件,就像我所描述的那样? - mike
@mike 这个输出是 7 吗? - Iharob Al Asimi
@mike 抱歉,应该是 if (*endptr == '\0') 而不是 if (*endptr != '\0')。我已经修复了,它应该会输出 7 - Iharob Al Asimi

2
这是一种可以写入和读取二进制文件的方法。在从中读取内容之前,您应该了解二进制文件和ASCII文件之间的区别。请先阅读https://stackoverflow.com/a/28301127/3095460并理解您正在使用代码读取的文件类型。
如果您在编辑器中打开一个文件并看到00000000000000000000000000000111,这并不意味着它是二进制文件,大多数编辑器仅将文件处理为ASCII文本文件。您需要使用二进制编辑器打开二进制文件,并从中读取有意义的数据。
#include <stdio.h>

int main()
{
    FILE *Read_fptr  = NULL;
    FILE *Write_fptr = NULL;
    int   data       = 20;
    size_t nElement  = 1;

    if ( (Write_fptr = fopen("data.bin", "wb")) != NULL ) {
        if ( fwrite(data, nElement, sizeof data, Write_fptr) != sizeof data ) {
            fprintf(stderr,"Error: Writing to file\n");
            fclose(Write_fptr);
            return -1;
        }
    } else {
        fprintf(stderr,"Error: opening file for writing\n");
        return -1;
    }
    fclose(Write_fptr);
    data = 0;
    if ( (Read_fptr = fopen("data.bin", "rb")) != NULL ) {
        if ( fread(data, nElement, sizeof data, Read_fptr) != sizeof data) {
            if( !feof(Read_fptr) ) {
                fprintf(stderr,"Error: Reading from file\n");
                fclose(Read_fptr);
                return -1;
            }
        }
    } else {
        fprintf(stderr,"Error: opening file for reading\n");
        return -1;
    }
    fclose(Read_fptr);

    printf("%d\n",data);
    return 0;

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接