[英]confusion about printf() in C
我正在尝试使用以下代码对文件进行 hexdump:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define SIZE 16
void pre_process(char buffer[],int len);
int main(int argc, char **argv){
if(argc == 2){
char *file = argv[1];
FILE *input = fopen(file,"r");
char buffer[SIZE];
char *tmp = malloc(4);
while(!feof(input)){
printf("%06X ",ftell(input)); /*print file pos*/
fread(buffer,1,SIZE,input); /*read 16 bytes with buffer*/
for (int i=0;i<SIZE;i += 4){ /*print each 4 bytes with hex in buffer*/
memcpy(tmp,buffer+i,4);
printf("%08X ",tmp);
}
printf("*");
pre_process(buffer,SIZE); /*print origin plain-text in buffer. subsitute unprint char with '*' */
printf("%s",buffer);
printf("*\n");
}
free(tmp);
fclose(input);
}
}
void pre_process(char buffer[],int len){
for (int i=0;i<len;i++){
if(isblank(buffer[i]) || !isprint(buffer[i]))
buffer[i] = '*';
}
}
从指环王那里读取切片,结果如下:在此处输入图像描述
那么,为什么十六进制代码都一样? printf("%08X ",tmp);
看起来有问题谢谢你的帮助。
答案就在这里:
memcpy(tmp,buffer+i,4);
printf("%08X ",tmp);
您可能已经知道memcpy
将4
个字节从buffer+i
复制到tmp
指向的位置。
即使这是在循环中完成的, tmp
仍会继续保存特定位置的地址,该地址永远不会改变。 每次调用memcpy()
都会更新 memory 中该地址/位置的内容。
简而言之,房子只留在那里,因此地址保持不变,但人们换了地方,新的人来了,老的人被消灭了!
此外,这里还有很多需要改进/修复的地方。 我建议从编译器的-Wall
选项启用警告开始。
tmp
存储缓冲区的地址; 该地址永远不会改变。 您要打印的是tmp
指向的缓冲区的内容。 在这种情况下, tmp
指向一个 4 char
的缓冲区; 如果你写
printf( "%08X ", *tmp );
您将只打印第一个元素的值 - 由于tmp
的类型为char *
,因此表达式*tmp
的类型为char
并且等效于编写tmp[0]
。
要将这些字节中的内容视为unsigned int
(这是%X
转换说明符所期望的),您需要在取消引用之前将指针转换为正确的类型:
printf( "%08X ", *(unsigned int *) tmp );
我们首先必须将tmp
从char *
转换为unsigned int *
,然后取消引用结果以获得这四个字节的unsigned int
等价物。
这假设您的系统上的sizeof (unsigned int) == 4
- 为了安全起见,您应该将malloc
调用编写为
char *tmp = malloc( sizeof (unsigned int) );
和
for ( int i = 0; i < SIZE; i += sizeof (unsigned int) )
{
memcpy( tmp, buffer + i, sizeof (unsigned int) );
...
}
反而。
您不应该使用feof
作为循环条件 - 在您尝试读取文件末尾之前它不会返回 true,因此您的循环会经常执行一次。 您需要查看fread
的返回值以确定您是否已到达文件末尾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.