C语言编程实现linux od 命令

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命令:

C语言编程实现linux od 命令

观察od -tx -tc 命令:容易看出 以十六进制输出ascii码 并在相应位置输出字符
并且 -tx 是以四字节为一组进行输出
并在行首端惊醒字符统计

实现思路:

从命令行参数读入文件;
    if(参数为目标文件){
	while(未到达文件末尾){
		将文件以字节为单位读入一个定长数组(16字节);
		分别以%c和%x格式依次输出数组中的内容;}

问题&解决

问题:观察以四字节进行输出的十六进制ascii编码为 字节倒序

C语言编程实现linux od 命令

原因:

我认为这是因为以字节入堆存储

所以高位存在低地址了

这就导致了逆序

解决方案:

个人感觉这样很别扭

所以通过单字符读取 并正序输出

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构造不当

C语言编程实现linux od 命令

原因:

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指令源代码。

C语言编程实现linux od 命令

ps:工程代码太难了,读都读不懂,就好像不是C语言一样,反思自己对c语言的理解还是太过浅显。

OpenEuler项目管理与实现

项目结构

C语言编程实现linux od 命令

代码调试

C语言编程实现linux od 命令

makefile

C语言编程实现linux od 命令

C语言编程实现linux od 命令

myod运行截图

C语言编程实现linux od 命令

静态库与动态库的制作

选项 含义
-static 链接静态库,禁止使用动态库
-shared 进行动态库编译,链接动态库
-Ldir 在动态库的搜索路径中增加dir目录
-lname 链接静态库(libname.a)或动态库(libname.so)的库文件
-fPIC(或fpic) 生成使用相对地址无关的目标代码

制作静态库

ar rcs lib/myod.a lib/myodP.o

C语言编程实现linux od 命令

使用静态库编译:gcc -static lib/main.o lib/myod.a -o myod1

制作动态库

gcc src/main.c src/myodP.c -I include -fPIC -o lib/libmyod.so

C语言编程实现linux od 命令

使用动态库编译: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

上一篇:(转)jQuery Mobile 移动开发中的日期插件Mobiscroll 2.3 使用说明


下一篇:Myod 选做