[英]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;
}
seek
ing is not needed seek
unsigned char
unsigned char
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.