C:从二进制文件中读取字节

5

我目前正在尝试从一个二进制文件中读取256个字节,但在运行程序时没有任何输出(或错误)。我有点困惑我做错了什么。我尝试将每个byte作为char读取并存储为长度为256的char数组。我已经查看了SO上类似的问题,但到目前为止还没有任何运气。下面是我的代码简化版本:

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

int main(int argc, char *argv[]){
    FILE *binary = fopen(argv[1], "rb");
    char bytesFromBinary[256];

    fread(&bytesFromBinary, 1, 256, binary);
    printf("%s", bytesFromBinary);
    return 0;
}

9
你正在尝试读取 二进制 数据并使用 字符串 格式说明符进行打印。如果该二进制数据以空字节开头或字节都是不可打印的值,你期望得到什么输出?或者如果这些字节 包含用来告诉 printf 停止打印的空终止符会发生什么? - Ken White
1
通过迭代数组并将每个数组值作为数字打印出来,可以帮助您查看数组中的内容,因为它不会解释扩展或受限制的ASCII字符,而是作为整数值。 - callyalater
文件的实际内容是什么?你能贴出一小段代码吗? - Fiddling Bits
这只是一个 .bin 文件。即使在记事本++中打开,也无法看到任何有意义的内容。 - GregH
3
为什么你指望 printf 输出有意义的东西呢? - user253751
3个回答

5

fread的基本用法是检查返回值是否符合预期读取的字节数,以验证您读取了预期内容。保存返回值可以使您处理部分读取。

以下最小化示例每次从给定作为第一个参数的文件(如果没有提供文件,则默认为stdin)中以16字节为单位读取到buf中,然后以十六进制格式将每个值输出到stdout

#include <stdio.h>

#define BUFSZ 16

int main (int argc, char **argv) {

    unsigned char buf[BUFSZ] = {0};
    size_t bytes = 0, i, readsz = sizeof buf;
    FILE *fp = argc > 1 ? fopen (argv[1], "rb") : stdin;

    if (!fp) {
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    /* read/output BUFSZ bytes at a time */
    while ((bytes = fread (buf, sizeof *buf, readsz, fp)) == readsz) {
        for (i = 0; i < readsz; i++)
            printf (" 0x%02x", buf[i]);
        putchar ('\n');
    }
    for (i = 0; i < bytes; i++) /* output final partial buf */
        printf (" 0x%02x", buf[i]);
    putchar ('\n');

    if (fp != stdin)
        fclose (fp);

    return 0;
}

注意: 当使用 fread 函数时,只有当 size 参数为 1 时,才有 bytes == readsz。返回结果是读取的 items 数量,每个项目仅对于 char 类型值等于 1示例用法/输出
$ echo "A quick brown fox jumps over the lazy dog" | ./bin/fread_write_hex
 0x41 0x20 0x71 0x75 0x69 0x63 0x6b 0x20 0x62 0x72 0x6f 0x77 0x6e 0x20 0x66 0x6f
 0x78 0x20 0x6a 0x75 0x6d 0x70 0x73 0x20 0x6f 0x76 0x65 0x72 0x20 0x74 0x68 0x65
 0x20 0x6c 0x61 0x7a 0x79 0x20 0x64 0x6f 0x67 0x0a

请查看示例,如果您有任何问题,请告诉我。

0

您没有声明足够长的变量。

您的声明char bytesFromBinary [256];保留了256个字节,而fread填充了所有256个字节。没有尾随的'\0',也没有空间,因此内存中的任何内容都会被覆盖/破坏。这已经会导致各种随机错误和崩溃。

然后,在printf中,您尝试打印它,该函数将一直运行到遇到'\0'才停止,因此如果程序到达那里,您将得到一个内存输出,可能很短,也可能有数千个(不可打印)字符。

您需要始终声明变量更长一些,以便有空间容纳尾随的'\0'char bytesFromBinary [257];。更好的方法是在fread中使用sizeof(var)-1,或者使用常量来指定长度并声明为+1。


更改为 bytesFromBinary[257] 并输出相同结果(无)。 - GregH

-1

它失败是因为你试图将一块字节作为C风格字符串打印。

有两种类型的文件:二进制文件和文本文件。要读/写文件,应以相应模式打开它。

如果您的文件是这样创建的:

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

int main(int argc, char *argv[])
{
    FILE *binary = fopen("file.txt", "wbx");
    if(!binary)
    {
        perror("fopen()");
        exit(EXIT_FAILURE);
    }
    char bytesToBinary[256] = ":-)";

    fwrite(bytesToBinary, 1, 256, binary);
    fclose(binary);
    return 0;
}

你的代码应该成功运行。


我正在以二进制模式打开文件,因为它是一个二进制文件。不确定你在这里要修复什么。 - GregH
二进制意味着“不可打印字符”。如果您尝试打印它们,您会得到奇怪的行为。 - Aganju
这里的问题不是它没有以二进制模式打开。 - user253751
此外,在我遇到的任何操作系统上,都没有两种类型的文件。文本文件是包含ASCII(或Unicode)字符的文件,而二进制文件则不是。 - user253751
@immibis 我怀疑要读取的文件是一个文本文件 - nalzok
显示剩余4条评论

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