虽然说要重点描述遇到的问题和解决过程,但是我基本没遇到什么问题。。。
除了一开始误认为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