虽然说要重点描述遇到的问题和解决过程,但是我基本没遇到什么问题。。。
除了一开始误认为od的地址栏是16进制的,还好后来觉得不对劲,发现了它是8进制
还有大于127的字节数据,也是8进制输出的
写完之后,感觉自己程序的性能应该还有改进的空间,fread每次应该还能读更多的字符,但为了方便处理,就没那么做
再就是代码应该还能更加简洁
gdb 还要注意一下,.o 文件不能 -g生成调试信息
用set args设置命令行的输入的参数
调试后发现不可见字符落了一个DEL (十进制ascii 127)
我觉得od也应该把不可见字符ascii对应的字符写出来,就像nodepad++一样,所以我就给写出来了,而没有用8进制的数值。
比如 1 => SOH ... 127=>DEL
myod 运行截图
.o文件
文本文件
od -tx -tc
.o文件
文本文件
源代码
#include "myod.h" int main(int argc,const char *argv[]){ FILE *fp = fopen(argv[1],"rb"); if(fp==NULL){ perror("file open error"); return -1; } unsigned char buf[16]; int n = 0; int i = 0; unsigned char ch = '\0'; while((n=fread(&ch,sizeof(char),1,fp))>0){ //8进制输出地址 if(i%16==0){ printf("%07o\t\t",i); } //将输入存入数组buf中 buf[i%16] = ch; //每四个字节一组,16进制打印输出 if(i%4==3){ printf("%02x%02x%02x%02x\t",buf[i%16],buf[i%16-1],buf[i%16-2],buf[i%16-3]); } //换行,以及换行后打印上一行16进制对应的字符 if(i%16==15){ printf("\n\t"); for(int j=0;j<16;j++){ if(j%4==0){printf("\t");} if(buf[j]>127){ printf("%o ",buf[j]); }else{ //myprintf主要用于打印不可见字符 myprintf(buf[j]); } } printf("\n"); } i++; } //循环结束后,还差最后一行16进制的字符没有打印 //继续处理 printf("\n\t"); for(int j=0;j<i%16;j++){ if(j%4==0){printf("\t");} if(buf[j]>127){ printf("%o ",buf[j]); }else{ myprintf(buf[j]); } } printf("\n"); fclose(fp); return 0; }
myprintf.c
6 #include <stdio.h> 7 void myprintf(int ch){ 8 switch(ch){ 9 case 0: 10 printf("\\0 "); 11 break; 12 case 1: 13 printf("SOH "); 14 break; 15 case 2: 16 printf("STX "); 17 break; 18 case 3: 19 printf("ETX "); 20 break; 21 case 4: 22 printf("EOT "); 23 break; 24 case 5: 25 printf("ENQ "); 26 break; 27 case 6: 28 printf("ACK "); 29 break; 30 case 7: 31 printf("\\a "); 32 break; 33 case 8: 34 printf("\\b "); 35 break; 36 case 9: 37 printf("\\t "); 38 break; 39 case 10: 40 printf("\\n "); 41 break; 42 case 11: 43 printf("\\v "); 44 break; 45 case 12: 46 printf("\\f "); 47 break; 48 case 13: 49 printf("\\r "); 50 break; 51 case 14: 52 printf("SO "); 53 break; 54 case 15: 55 printf("SI "); 56 break; 57 case 16: 58 printf("DLE "); 59 break; 60 case 17: 61 printf("DC1 "); 62 break; 63 case 18: 64 printf("DC2 "); 65 break; 66 case 19: 67 printf("DC3 "); 68 break; 69 case 20: 70 printf("DC4 "); 71 break; 72 case 21: 73 printf("NAK "); 74 break; 75 case 22: 76 printf("SYN "); 77 break; 78 case 23: 79 printf("ETB "); 80 break; 81 case 24: 82 printf("CAN "); 83 break; 84 case 25: 85 printf("EM "); 86 break; 87 case 26: 88 printf("SUB "); 89 break; 90 case 27: 91 printf("ESC "); 92 break; 93 case 28: 94 printf("FS "); 95 break; 96 case 29: 97 printf("GS "); 98 break; 99 case 30: 100 printf("RS "); 101 break; 102 case 31: 103 printf("US "); 104 break; 105 case 127: 106 printf("DEL "); 107 break; 108 default: 109 printf("%c ",ch); 110 break; 111 } 112 }
myod.h
1 #ifndef _MYOD_H_ 2 #define _MYOD_H_ 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 7 //输出不可见字符对应的ascii字符 8 void myprintf(int ch); 9 10 #endif
程序也没什么问题,gdb设置个命令行参数,就往下跑完了
更多关于gdb,我的博客1
更多关于gdb,我的博客2
Makefile
1 src = $(wildcard src/*.c) 2 obj = $(patsubst %.c,%.o,$(src)) 3 4 myArgs= -Iinclude -Llib -Wall 5 6 ALL:a.out 7 8 a.out:$(obj) 9 -gcc lib/*.o -o $@ $(myArgs) 10 11 $(obj):%.o:%.c 12 gcc -c $< -o lib/$(notdir $@) $(myArgs) 13 14 clean: 15 -rm -rf lib/*.o a.out 16 17 .PHONY: clean ALL test 18 19 test: 20 @echo $(src) 21 @echo $(obj)
make clean & make
制作动态库
gcc -c -fPIC src/myprintf.c -o lib/dymyprintf.o -Iinclude
gcc -shared -o lib/libdymyod.so lib/dymyprintf.o
export LD_LIBRARY_PATH=./lib
gcc src/myod.c -ldymyod -Llib -Iinclude
./a.out res/binwrite.txt
制作静态库
ar rcs lib/libmyod.a lib/myprintf.o
gcc src/myod.c -Iinclude -Llib -lmyod -o b.out
./b.out res/binwrite.txt