简体   繁体   English

C用fread()读取二进制文件

[英]C Reading binary file with fread()

im trying to read file from stdin with hex values: 我试图从具有十六进制值的标准输入中读取文件:

0x0a 0X0A

0x00 0x0a 0x00 0x0a

0x61 0x00 0x61 0x00 0x0a 0x61 0x00 0x61 0x00 0x0a

0x00 0x00 0x00 0x00 0x00 0x00

int i = 0;
unsigned char x = 0;        
            while(x != 0x0a && x != EOF){
                fread(&x, 1 , 1, stdin);
                tab[i] = x;
                i++;
            }

With this loop i'm getting segmentation fault with last line. 有了这个循环,我得到最后一行的分段错误。

Without seeing the declaration of tab we can't really be certain what is triggering the segfault (most likely out of bounds access to tab ). 在没有看到tab的声明的情况下,我们无法真正确定是什么触发了segfault(很可能是超出对tab访问范围)。

However, you shouldn't use fread with stdin - fread is for reading binary files, it will read the binary representation of every character on the screen. 但是,你不应该使用freadstdin - fread是用于读取二进制文件,它会在屏幕上阅读每个字符的二进制表示。 You are actually reading a byte representation of a character, pretty much the same as if you were doing x = getchar() or scanf("%c", &x) 实际上,您正在读取字符的字节表示形式,与执行x = getchar()scanf("%c", &x)几乎相同

So you will read "0x0a\\n0x00 0x0a\\n" etc. 因此,您将看到“ 0x0a \\ n0x00 0x0a \\ n”等。

Now, you are testing it against the value of 0x0a , which is actually a '\\n' , so you likely aren't reading past the first line. 现在,您正在针对0x0a值(实际上是'\\n' ,因此您可能没有读过第一行。

What you want to be doing is: 您想做的是:

scanf("0x%x", &x);

Which will read a single hex value, such as "0x0a", which you can then check against that constant above. 它将读取单个十六进制值,例如“ 0x0a”,然后您可以根据上面的常数进行检查。

Another thing - You have declared x as an unsigned char , but are testing it against EOF , which is an int, -1 . 另一件事-您已将x声明为unsigned char ,但正在针对EOF (即int -1 I'm surprised the compiler didn't give you a warning there. 我很惊讶编译器没有向您发出警告。 You should pretty much always read the value into an int, so I'd redeclare it as int . 您应该几乎总是将值读入int,因此我将其重新声明为int

Also, when reading binary files (ie using fread ), you will never read the EOF value, since that is a valid value to be found in the file. 同样,在读取二进制文件时(即使用fread ),您将永远不会读取EOF值,因为该值是在文件中可以找到的有效值。 Instead, if end of file has been reached, fread will return 0. And you can check whether it has been reached using feof(file) . 相反,如果已到达文件末尾,则fread将返回0。您可以使用feof(file)检查是否已到达它。

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

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