简体   繁体   English

C编程:如何从二进制文件中读取和打印一个字节?

[英]C Programming : how do I read and print out a byte from a binary file?

I wish to open a binary file, to read the first byte of the file and finally to print the hex value (in string format) to stdout (ie, if the first byte is 03 hex, I wish to print out 0x03 for example). 我希望打开一个二进制文件,读取文件的第一个字节,最后将十六进制值(字符串格式)打印到stdout(即,如果第一个字节是03十六进制,我希望打印出0x03例如) 。 The output I get does not correspond with what I know to be in my sample binary, so I am wondering if someone can help with this. 我得到的输出与我在样本二进制文件中所知的不一致,所以我想知道是否有人可以帮助解决这个问题。

Here is the code: 这是代码:

#include <stdio.h>
#include <fcntl.h>

int main(int argc, char* argv[])
{
int fd;
char raw_buf[1],str_buf[1];

fd = open(argv[1],O_RDONLY|O_BINARY);

    /* Position at beginning */
lseek(fd,0,SEEK_SET);

    /* Read one byte */
read(fd,raw_buf,1);

    /* Convert to string format */
sprintf(str_buf,"0x%x",raw_buf);
printf("str_buf= <%s>\n",str_buf);

close (fd);
return 0;   
}

The program is compiled as follows: 该计划编制如下:

gcc rd_byte.c -o rd_byte gcc rd_byte.c -o rd_byte

and run as follows: 运行如下:

rd_byte BINFILE.bin rd_byte BINFILE.bin

Knowing that the sample binary file used has 03 as its first byte, I get the output: 知道使用的样本二进制文件有03作为其第一个字节,我得到输出:

str_buf= <0x22cce3> str_buf = <0x22cce3>

What I expect is str_buf= <0x03> 我期望的是str_buf = <0x03>

Where is the error in my code? 我的代码中的错误在哪里?

Thank you for any help. 感谢您的任何帮助。

You're printing the value of the pointer raw_buf , not the memory at that location: 您正在打印指针raw_buf的值,而不是该位置的内存:

sprintf(str_buf,"0x%x",raw_buf[0]);

As Andreas said, str_buf is also not big enough. 正如安德烈亚斯所说, str_buf也不够大。 But: no need for a second buffer, you could just call printf directly. 但是:不需要第二个缓冲区,你可以直接调用printf

printf("0x%x",raw_buf[0]);

Less is more... 少即是多...

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
    int fd;
    unsigned char c;

    /* needs error checking */
    fd = open(argv[1], O_RDONLY);
    read(fd, &c, sizeof(c));
    close(fd);

    printf("<0x%x>\n", c);
    return 0;
}
  1. seek ing is not needed 不需要seek
  2. if you want to read a byte use an unsigned char 如果要读取一个字节,请使用unsigned char
  3. printf will do the format printf将执行格式化

I think that you are overcomplicating things and using non-portable constructs where they aren't really necessary. 我认为你过度复杂的东西和使用非便携式结构,他们并不是真的有必要。

You should be able to just do: 你应该能够做到:

#include <stdio.h>

int main(int argc, char** argv)
{
    if (argc < 2)
        return 1; /* TODO: better error handling */

    FILE* f = fopen(argv[1], "rb");

    /* TODO: check f is not NULL */

    /* Read one byte */    
    int first = fgetc(f);

    if (first != EOF)
        printf("first byte = %x\n", (unsigned)first);

    /* TODO else read failed, empty file?? */

    fclose(f);

    return 0;
}

str_buf has a maximum size of 1 ( char str_buf[1]; ), it should at least 5 bytes long (4 for XxXX plus the \\0). str_buf的最大大小为1( char str_buf[1]; ),它应该至少5个字节长(4个用于XxXX加上\\ 0)。

Moreover, change 而且,改变

sprintf(str_buf,"0x%x",raw_buf);

to

sprintf(str_buf,"0x%x",*raw_buf);

otherwise you'll print the address of the raw_buf pointer, instead of its value (that you obtain by dereferencing the pointer). 否则你将打印raw_buf指针的地址,而不是它的值(通过取消引用指针获得)。

Finally, make sure both raw_buf is unsigned . 最后,确保raw_buf都是unsigned The standard specified that the signness of chars (where not explicitly specified) is implementation defined, ie, every implementation decides whether they should be signed or not. 该标准规定了chars的符号(未明确指定)是实现定义的,即每个实现都决定是否应该签名。 In practice, on most implementations they are signed by default unless you're compiling with a particular flag. 实际上,在大多数实现中,除非您使用特定标志进行编译,否则它们将默认签名。 When dealing with bytes always make sure they are unsigned; 处理字节时总是确保它们是无符号的; otherwise you'll get surprising results should you want to convert them to integers. 如果你想将它们转换为整数,你会得到令人惊讶的结果。

Using the information from the various responses above (thank you all!) I would like to post this piece of code which is a trimmed down version of what I finally used. 使用上面各种响应中的信息(谢谢大家!)我想发布这段代码,这是我最终使用的修剪版本。

There is however a difference between what the following code does and what was described in my origal question : this code does not read the first byte of the binary file header as described originally, but instead reads the 11th and 12th bytes (offsets 10 & 11) of the input binary file (a .DBF file). 但是,下面的代码与我的原始问题中描述的内容之间存在差异:此代码不读取最初描述的二进制文件头的第一个字节,而是读取第11个和第12个字节(偏移量10和11) )输入二进制文件(.DBF文件)。 The 11th and 12th bytes contain the length of a data record (this is what I want to know in fact) with the Least Significant Byte positioned first: for example, if the 11th and 12th bytes are respectivly : 0x06 0x08, then the length of a data record would be 0x0806 bytes, or 2054bytes in decimal 第11个和第12个字节包含数据记录的长度(这实际上是我想知道的),其中最低有效字节位于第一位:例如,如果第11和第12个字节分别是:0x06 0x08,则长度为数据记录为0x0806字节,或十进制2054字节

 #include <stdio.h>
 #include <fcntl.h>

 int main(int argc, char* argv[]) {
 int fd, dec;
 unsigned char c[1];
 unsigned char hex_buf[6];

 /* No error checking, etc. done here for brevity */

 /* Open the file given as the input argument */
 fd = open(argv[1], O_RDONLY);

 /* Position ourselves on the 11th byte aka offset 10 of the input file */
 lseek(fd,10,SEEK_SET);

 /* read 2 bytes into memory location c */
 read(fd, &c, 2*sizeof(c));

 /* write the data at c to the buffer hex_buf in the required (reverse) byte order + formatted */
 sprintf(hex_buf,"%.2x%.2x",c[1],c[0]);
 printf("Hexadecimal value:<0x%s>\n", hex_buf);

 /* copy the hex data in hex_buf to memory location dec, formatting it into decimal */
 sscanf(hex_buf, "%x", &dec);

 printf("Answer: Size of a data record=<%u>\n", dec);

 return 0;

} }

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

相关问题 如何读取和打印 C 中的二进制文件? - How do I read and print a binary file in C? 如何在二进制* .dat文件中存储信息或从中打印信息? C程序设计 - How to store in or print information from a binary *.dat file? C programming 如何读取存储在二进制文件中的数组或变量,并在程序中将其打印出来? - How do I read an array or variable that is stored in a binary file, and print it out in the program? 如何在 C 中一次从二进制文件中读取半字节? - How to read only half a byte from a binary file at a time in C? 如何从需要每个元素不同字节长度的外部二进制文件中读取数据? - How do I read in data from an external binary file that needs differing byte lengths per element? C编程:从文件读取并在屏幕上打印 - C Programming: Read from file and print on screen 读取二进制文件 C 编程 - Read a binary file C programming 读取一个充满整数的二进制文件,并以C的ASCII格式打印出来 - Read a binary file full of integers and print it out in an ASCII format in C C编程如何将字符串读入数组并正确打印回去? - C Programming How to read a string into an array and print it back out properly? 如何打印输入文件中的二进制字符? - How do I print the binary of characters from an input file?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM