我希望打开一个二进制文件,读取文件的第一个字节,最后将十六进制值(字符串格式)打印到stdout(即,如果第一个字节是03十六进制,我希望打印出0x03例如)。我得到的输出与我在样本二进制文件中所知的不一致,所以我想知道是否有人可以帮助解决这个问题。
以下是代码:
#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;
}
该程序编译如下:
gcc rd_byte.c -o rd_byte
并按如下方式运行:
rd_byte BINFILE.bin
知道使用的样本二进制文件的第一个字节是03,我得到输出:
str_buf =&lt; 0x22cce3&gt;
我的期望是什么 str_buf =&lt; 0x03&gt;
我的代码中的错误在哪里?
感谢您的帮助。
答案 0 :(得分:7)
您正在打印指针raw_buf
的值,而不是该位置的内存:
sprintf(str_buf,"0x%x",raw_buf[0]);
正如安德烈亚斯所说,str_buf
也不够大。但是:不需要第二个缓冲区,你可以直接调用printf
。
printf("0x%x",raw_buf[0]);
答案 1 :(得分:5)
少即是多......
#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
不需要unsigned char
printf
将采用格式答案 2 :(得分:4)
我认为你过度复杂化并使用非便携式结构,而这些结构并非真正必要。
你应该能够做到:
#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;
}
答案 3 :(得分:2)
str_buf
的最大大小为1(char str_buf[1];
),长度至少应为5个字节(XxXX加上\ 0为4)。
此外,改变
sprintf(str_buf,"0x%x",raw_buf);
到
sprintf(str_buf,"0x%x",*raw_buf);
否则你将打印raw_buf
指针的地址,而不是它的值(你通过取消引用指针获得的)。
最后,确保raw_buf都是unsigned
。该标准规定了chars的符号(未明确指定)是实现定义的,即每个实现都决定是否应该签名。实际上,在大多数实现中,除非您使用特定标志进行编译,否则它们将默认签名。处理字节时总是确保它们是无符号的;如果你想将它们转换成整数,你会得到令人惊讶的结果。
答案 4 :(得分:0)
使用上面各种回复中的信息(谢谢大家!)我想发布这段代码,这是我最终使用的修剪版本。
以下代码与我的原始问题中描述的内容之间存在差异:此代码不读取最初描述的二进制文件头的第一个字节,而是读取第11个和第12个字节(偏移量) 10&amp; 11)输入二进制文件(.DBF文件)。第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;
}