C语言编程实现linux od 命令
什么时od命令
od(octal dump)命令可以以八进制、十进制、十六进制和ASCII码的格式来显示文件或者流,它们对于访问或可视地检查文件中不能直接显示在终端上的字符(如换行符等)很有用。此外,在一些有空洞的文件中可以通过od命令查看空洞的位置。
使用方法:
od [-A 地址进制] [-t 显示格式] 文件名
o:八进制(系统默认值)
d:十进制
x:十六进制
n:不打印位移值
c:ASCII字符或反斜杠序列(如\n)
d:有符号十进制数
f:浮点数
o:八进制(系统默认值)
u:无符号十进制数
x:十六进制数
编写myod 以实现 od -tx -tc XXX
分析&设计
OpenEuler系统中使用od命令:
观察od -tx -tc 命令:容易看出 以十六进制输出ascii码 并在相应位置输出字符
并且 -tx 是以四字节为一组进行输出
并在行首端惊醒字符统计
实现思路:
从命令行参数读入文件;
if(参数为目标文件){
while(未到达文件末尾){
将文件以字节为单位读入一个定长数组(16字节);
分别以%c和%x格式依次输出数组中的内容;}
问题&解决
问题:观察以四字节进行输出的十六进制ascii编码为 字节倒序
原因:
我认为这是因为以字节入堆存储
所以高位存在低地址了
这就导致了逆序
解决方案:
个人感觉这样很别扭
所以通过单字符读取 并正序输出
fread()单字符读取
argc&argv
main(int argc, char *argv[ ], char **env)
argc: 整数,用来统计你运行程序时送给main函数的命令行参数的个数
*argv[ ]: 指针数组,用来存放指向你的字符串参数的指针,每一个元素指向一个参数
argv[0] 指向程序运行的全路径名
argv[1] 指向在DOS命令行中执行程序名后的第一个字符串
argv[2] 指向执行程序名后的第二个字符串
...
argv[argc]为NULL。
理解:argc就是传入参数的条数,第一条是本程序的路径,所以表示为传入参数+1
argv是存放传入参数的一个字符数组,具体含义如上。
问题:本想实现通过参数并无视传参顺序来执行命令,使用switch进行选择,但switch构造不当
原因:
switch 不支持字符串判据
解决方案:
使用od命令时,仅传入目标文件,避免判断。
问题:-tx -tc 指令实质上是将 目标文件通过两种格式输出,相当于打印两边,在第一次打印时预留好位置,第二次在插空打印另一种格式,这样可以将程序的函数更加结构化。OpenEuler系统下图形化函数为ncurses
curses.h函数库的int move(int new_y, int new_x)
;可以实现光标位置的移动。
原因:
运气非常差,通过yum安装时,遇到软件源崩溃,验证发现服务器404.
希望能尽快修复。
解决方案:
按行打印输出。
问题:如何输出行首字符统计计数,并将行与行之间尽可能对齐。
解决方案:
-
如何输出字符统计计数?
- 通过观察发现,每行开头这串数字为八进制,数值为在本行之前的字符数。所以,只需在prinf()函数中格式化输出printf("%07o",参数)即可。
-
如何使同一个字符的ASCII字符与对应的进制上下对齐?
- printf()的修饰符中,数字表示最小字段宽度。如果该字段不能容纳待打印的数字或字符串,系统会用更宽的字段。所以,例如printf("4d%",参数)即可打印宽度为4的十进制数。
未实现的功能
-
对于命令参数的无序输入
- 设想:字符串匹配
-
增加参数支持,并尽可能模块化
- 设想:维护一个函数队列,对于首先进入的参数,将其实现函数放入队列,待所有参数入队后,依次执行相应函数,打印输出。
参考:linux od指令源代码。
ps:工程代码太难了,读都读不懂,就好像不是C语言一样,反思自己对c语言的理解还是太过浅显。
OpenEuler项目管理与实现
项目结构
代码调试
makefile
myod运行截图
静态库与动态库的制作
选项 | 含义 |
---|---|
-static | 链接静态库,禁止使用动态库 |
-shared | 进行动态库编译,链接动态库 |
-Ldir | 在动态库的搜索路径中增加dir目录 |
-lname | 链接静态库(libname.a)或动态库(libname.so)的库文件 |
-fPIC(或fpic) | 生成使用相对地址无关的目标代码 |
制作静态库
ar rcs lib/myod.a lib/myodP.o
使用静态库编译:gcc -static lib/main.o lib/myod.a -o myod1
制作动态库
gcc src/main.c src/myodP.c -I include -fPIC -o lib/libmyod.so
使用动态库编译:gcc -I include src/main.c -Llib -lmyod -o myod2
参考资料
linux od命令详解: https://www.cnblogs.com/hdk1993/p/4395574.html
argc&argv: https://baike.baidu.com/item/argc argv/10826112
项目源码
码云:https://gitee.com/DKY2019/xxaqxt/blob/master/odd.c
附 linux od指令源代码: https://gitee.com/DKY2019/xxaqxt/blob/master/od.c
20191331lyx
2021/9/24