对Linux命令od -tc -tx1的C语言程序实现myod-优化版

导语

  • 自编od C语言实现版名为myod

  • 上个星期有一个初代版,链接- myod原版

  • 这星期的课上要求实现myod-系统调用版本,要求如下

    1 参考教材第十章内容

    2 用Linux IO相关系统调用编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能,注意XXX是文件名,通过命令行传入,不要让用户输入文件名

    3.不要把代码都写入main函数中

    4.要分模块,不要把代码都写入一个.c中

    5 提交测试代码和运行结果截图, 提交调试过程截图,要全屏,包含自己的学号信息

程序思路

结构

  • 判定命令行输入是否正确,错误则报错退出。
  • 对文件进行录入并存入字符数组str[]

    相关函数及头文件

函数头文件
open()#include <sys/types.h>;#include <sys/stat.h>;#include <fcntl.h>
read()#include <unistd.h>
  • 输出八位表示的累计字符
  • 输出最多十六个为一组的文本
  • 输出该组文本各字符的ASCII码
  • 对于每行最多处理16个字符,我使用的是for循环和一个计数函数count共同把控

变量说明

char str[BUFFERSIZE];存整个文本的字符串

int LJ;已累计表示了多少各字符

int SY;还剩下多少字符没有表示

int tSY,Dan;tSY其实是SY,但是为了分模块处理便于我自己的理解便改了个名称,Dan是单次表示字符个数,和tSY组合使用

int tx[8];char tx2[8];用于表示八位十六进制累计数字和ASCII码十六进制表示

补充知识点

  • read()在Linux C下,可以直接在终端用man查看,或者下载中文的man帮助文档,如果懒得翻可以打开该链接—— read()
  • open()同理—— 打开文件open()函数的使用方法详解--C语言函数
  • perror()同理——perror; perror 的用法

  • codeblocks整理代码:Plugins->Source code formatter(Astyle)

优化过程

代码对比

嫌弃版

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void One(int LJ,int tx[],char tx2[]);
void TX(int H,int tx[]);
char Change(int t);
void main(int argc,char *argv[])
{FILE *fp;if((fp = fopen(argv[4],"r")) == NULL){printf("   ***文件打开失败***");exit(0);}if(strcmp(argv[1], "od")==0){if(strcmp(argv[2], "-tc")==0){if(strcmp(argv[3], "-tx")==0){char str[1000];int num,i,j,i2;for(num=0; num<strlen(str); num++)str[num] = '0';num = 0;int fd;fd = open(argv[4], O_RDONLY);num = read(fd, str, sizeof(str));close(fd);int LJ;int SY;for(LJ = 0,SY = num;;){int tx[8];char tx2[8];for(j=0; j<8; j++)tx[j] = 0;One(LJ,tx,tx2);for(j=0; j<8; j++){printf("%c",tx2[j]);}printf(" ");//累计字符输出完毕int tSY,Dan;tSY = SY;//     do//     {if(tSY>=16){Dan = 16;}else{Dan = tSY;}for(j=LJ; j<Dan+LJ; j++){// printf("j = %d,Dan=%d\n",j,Dan);if(str[j]=='\n'){printf("\\n  ");}else{printf("%c \t",str[j]);}}//  putchar(str[i]);printf("\n");int tt;
//输出文本printf("         ");for(j=LJ; j<Dan+LJ; j++){tt = str[j];One(tt,tx,tx2);for(i2=0; i2<8; i2++){if(tx2[i2]!='0')printf("%c",tx2[i2]);}printf("  \t");}printf("\n");tSY = tSY-Dan;//     }//     while(tSY>0);printf("\n");//   printf("SY=%d,LJ=%d\n",SY,LJ);if(SY>=16){LJ = LJ+16;}else if((SY>0)&&(SY<16)){LJ = LJ+SY;}else if(SY==0){break;}SY = num-LJ;//        printf("SY=%d,LJ=%d\n",SY,LJ);}}}}else{printf("指令输入错误\n");}
//   printf("\nover\n");fclose(fp);
}
void One(int LJ,int tx[],char tx2[]){TX(LJ,tx);int i;//  printf("\n分界线\n");for(i=0; i<8; i++){//   printf("%d ",tx[i]);tx2[i] = Change(tx[i]);//     printf("%c",tx2[i]);}
}
void TX(int H,int tx[])
{if(H>536870911){printf("字符数太大,超出限制\n");exit (0);}int i=7;//  printf("LS = %d\n",H);for(; i>0;){tx[i] = H%16;H = H/16;i--;
//        printf(" H = %d,tx[%d] = %d\n",H,i+1,tx[i+1]);}
}
char Change(int t)
{//      printf("scs\n");if((t>=0)&&(t<10)){return t+48;}else{return t+87;}
}

优化版

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define BUFFERSIZE 1000
void Change(int LJ,int tx[],char tx2[]);
void dToH(int H,int tx[]);
char intToChar(int t);
int count(int *tSY,int *Dan,int *LJ,int *SY,int *num);
void outputAscii(char tx2[],int Dan,int LJ,int tx[],char str[]);
void main(int argc,char *argv[])
{char str[BUFFERSIZE];int num,i,j,i2;int fd;if((strcmp(argv[1], "od")!=0)|(strcmp(argv[3], "-tc")!=0)|(strcmp(argv[2], "-tx")!=0)){printf("输入格式错误");exit(0);}for(num=0; num<strlen(str); num++)str[num] = '0';num = 0;if ( (fd = open(argv[4], O_RDONLY)) == -1 ){perror(argv[4]);exit(1);}num = read(fd, str, BUFFERSIZE);close(fd);int LJ;int SY;int tx[8];char tx2[8];int tSY,Dan;for(LJ = 0,SY = num;;){for(j=0; j<8; j++)tx[j] = 0;Change(LJ,tx,tx2);for(j=0; j<8; j++){printf("%c",tx2[j]);}printf(" ");//累计字符输出完毕tSY = SY;if(tSY>=16){Dan = 16;}else{Dan = tSY;}for(j=LJ; j<Dan+LJ; j++){if(str[j]=='\n'){printf("\\n  ");}else{printf("%c \t",str[j]);}}printf("\n");//输出文本outputAscii(tx2,Dan,LJ,tx,str);if(2==count(&tSY,&Dan,&LJ,&SY,&num))exit(0);}
}
void Change(int LJ,int tx[],char tx2[]){dToH(LJ,tx);int i;for(i=0; i<8; i++){tx2[i] = intToChar(tx[i]);}
}
void dToH(int H,int tx[])//十进制转十六进制,但此时仍用int存储
{if(H>536870911){printf("字符数太大,超出限制\n");exit (0);}int i=7;for(; i>0;){tx[i] = H%16;H = H/16;i--;}
}
char intToChar(int t)//十六进制,把int[]转为char[]
{if((t>=0)&&(t<10)){return t+48;}else{return t+87;}
}
int count(int *tSY,int *Dan,int *LJ,int *SY,int *num)//计数并判定是否终止
{*tSY = *tSY-*Dan;printf("\n");if(*SY>=16){*LJ = *LJ+16;}else if((*SY>0)&&(*SY<16)){*LJ = *LJ+*SY;}else if(*SY==0){return 2;}*SY = *num-*LJ;return 1;
}
void outputAscii(char tx2[],int Dan,int LJ,int tx[],char str[])
{int tt,j,i2;printf("         ");for(j=LJ; j<Dan+LJ; j++){tt = str[j];Change(tt,tx,tx2);for(i2=0; i2<8; i2++){if(tx2[i2]!='0')break;}for(;i2<8;i2++)printf("%c",tx2[i2]);printf("  \t");}printf("\n");
}

改造过程

1.把没来得及删掉的用指针打开文件的那段fp = fopen(argv[4],"r"等删掉,有open就可以了

2.修改自编函数名称。当我回来再看代码时原先的名称确实无法提醒我到底它要做什么,(捂脸),所以组合型名称按照小驼峰式,单个词函数名用了首字母大写的方式,多谢老师指导与提醒~

3.判定命令行输入条件时取消那么多if,直接用“|”符号来限定选择条件

 if((strcmp(argv[1], "od")!=0)|(strcmp(argv[3], "-tc")!=0)|(strcmp(argv[2], "-tx")!=0))

4.将存文本的字符大小用宏定义BUFFERSIZE,提高程序的可读性与可维护性。解释:比如我想存一个10000的文本,但是之前的str[]只有1000,所以我只需要把define那里的BUFFERSIZE改掉,后面的就不用改了,否则还得满篇找1000改10000,这个程序短,所以还不觉得有什么,但是程序如果很大很复杂,这种情况不仅维护的人不好读懂代码,而且容易改漏。

5.使用perror()函数,添加报错功能。

6.将计数和输出ASCII码的功能从主函数中分离出来成为自编函数,使主程序显得不那么臃肿,更好读懂。

7.修改了一个程序上的错误

for(i2=0; i2<8; i2++){if(tx2[i2]!='0')printf("%c",tx2[i2]);}

这个输出会把所有0给抹掉,也是优化的时候才发现这个错误(捂脸)

修改为:

for(i2=0; i2<8; i2++){if(tx2[i2]!='0')break;}for(;i2<8;i2++)printf("%c",tx2[i2]);

代码链接

myod嫌弃版(合体)

myod优化版(合体)

myod优化版(模块化)

一阵瞎逼逼

第一个版本我本来就实现了命令行调用,并且并未只写在一个main函数里,就只需要改两个函数就可以了。当时课上电脑不知道被我改了哪里,找不到网络的开关……慌慌地改了代码交了,觉得代码还是有点丑,想着怎么再改改,眼瞎也没看到还有展开项-提交代码……

看到老师对之前博客的评论,越看我的代码越觉得……好嫌弃,确实需要好好改一改。于是真的有不少地方可以改……就有了对二代版的优化版。

之所以单开一篇博客是为了方便我日后记不到了好查找资料。是的,作为一个暑假之后就忘了放在学校电脑的开机密码的人真的不能对自己的记忆力多有信心。以后可能会在自己的博客里记录一些非常简单的知识。反正最终都会忘掉的,不如让再次自学的时候能轻松高效一些。

转载于:https://www.cnblogs.com/GDDFZ/p/7656052.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/571856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python字典求平均值_Python 3.4 – 如何获得字典值的平均值?

好吧,让我们迭代所有字典键并平均项目&#xff1a; avgDict {} for k,v in StudentGrades.iteritems(): # v is the list of grades for student k avgDict[k] sum(v)/ float(len(v)) 现在你可以看到&#xff1a; avgDict Out[5]: {Ivan: 3.106666666666667, Martin: 4.81666…

PHP使用指南,PHP使用指南-cookies部分

php使用指南-cookies部分在这课教程我们将学习怎样利用 PHP 处理cookies,我将试着使事情尽可能简单地去解释cookies的一些实际应用。什么是cookies及作用&#xff1f;cookies是由web服务器产生的并且存在客户端的一些信息。它嵌在html信息中&#xff0c;由服务器端指定&#xf…

python猜数字游戏猜n次_python实践项目四:猜数字游戏

1 #!/usr/bin/python 2 #-*- coding: UTF-8 -*- 3 4 importrandom5 secretNumberrandom.randint(1,20)6 print "Im thinking of a number between 1 and 20." 7 times 08 for i in range(1,7):9 print "Take a guess:" 10 guessint(input())11 if guess

使用Linux记录

更新时间: 2018-12-12 Linux Usage 缘起&#xff1a;最近将系统更换为Linux&#xff0c;虽然之前有用过&#xff0c;但只是当作尝试&#xff0c;未当为主系统&#xff0c;这次下定决心以它为主系统&#xff0c;懒得去纠结使用win的一种不道德感及不爽感&#xff0c;游戏及娱乐与…

使用java实现rfc3161,openssl验证用自签名证书签名的RFC3161时间戳

我使用openssl从rfc 3161 timestampreq生成了一个rfc3161 timestampresp。因此,我使用了自签名CA证书和自签名CA使用以下命令颁发的TSA证书:openssl ts -reply -queryfile request.tsq -signer TSAcert.pem -out response.tsr已创建响应。openssl ts -reply -text -in response…

halcon 旋转_Halcon视觉软件应该如何系统学习?

End 声明&#xff1a;部分内容来源于网络&#xff0c;仅供读者学习、交流之目的。文章版权归原作者所有。如有不妥&#xff0c;请联系删除。

java使用重复的类库,java list 去除 重复值

一&#xff1a;Hastset根据hashcode判断是否重复&#xff0c;数据不会重复Java代码/** List order not maintained **/public static void removeDuplicate(ArrayList arlList){HashSet h new HashSet(arlList);arlList.clear();arlList.addAll(h);}二&#xff1a;通过Hashset…

JavaScript--关于变量提升思考

下面例子仅仅是思考变量提升使用&#xff1a; 在实际开发中并不推荐使用相同名字的变量和函数&#xff01; 1 // 如果变量和函数同名的话&#xff0c;函数优先提升 2 console.log(a); 3 function a() { 4 console.log(aaaaa); 5 } 6 var a 1; 7 console.log(a); 更多简单经典…

C++求复数的角度_【研读.教材分析】“勾股定理”教学——基于单元整体的角度再思考...

(西安市第八十六中学 刘丽丽)学科教学要注重知识的“生长点”和“延伸点”&#xff0c;把课时知识置于学科整体逻辑体系中&#xff0c;关注结构和通法&#xff0c;处理好局部与整体之间的关系。所以在北师大版八年级上册数学第一章《勾股定理》的备课中&#xff0c;我再次以问…

java 十进制 左移,java移位运算符之十进制转二进制

本次MS08-067严重漏洞各系统补丁地址如下&#xff1a;中文操作系统KB958644补丁下载地址&#xff1a;Windows Vista 安全更新程序 (KB958644)Windows Server 2008 x64 Edition 安全更新程序 (KB958644)Windows Server 2003 x64 Edition 安全更新程序 (KB958644)Windows Server …

angualr 单选全选方法(适用购物车/各种列表删除等)

Html部分&#xff1a; <table class"pay_attention_table"><thead><tr><!--ng-click"all(selectAll)"--><th class"c_aa w52"><input type"checkbox" class"mr4" ng-model"selectObj…

vc++64位系统下long的长度为4个字节_Java与系统硬件的亲密接触「伪共享」

作者&#xff1a;码洞来源&#xff1a;https://zhuanlan.zhihu.com/p/32764602在解释【伪共享】这个概念之前&#xff0c;我们先来运行一段代码&#xff0c;小编的电脑上有4个core。这个程序的逻辑是4个线程共享同一个数组读写不同下标的变量。每个线程循环1亿次读写&#xff0…

快捷登录PHP,phpcms 微信快捷登陆

上一篇文章&#xff0c;给大家分享了关于微信授权登陆功能&#xff0c;今天给大家分享一个微信快捷登陆的实际用例。phpcms接入微信快捷登陆第一步&#xff0c;在login方法中&#xff0c;判定是否使用微信浏览器访问&#xff0c;如果是&#xff0c;发起授权申请if ( strpos($_S…

linux 端口号查看

linux 端口号查看netstat -anp |grep 端口号最后一列是端口号转载于:https://www.cnblogs.com/ditmark/p/7669804.html

pwm波如何控制电机代码_PWM波控制720电机

详细方案四&#xff1a;pwm与720电机控制电机硬件分析什么是电机&#xff1f;电机(俗称"马达")是指依据电磁感应定律实现电能转换或传递的一种电磁装置。它的主要作用是产生驱动转矩&#xff0c;作为用电器或各种机械的动力源。其中本四轴采用的电机是直流电机。直流…

php里的stdclass,PHP中的stdClass是什么?

stdClass是另一个很好的PHP特性。您可以创建一个匿名PHP类。让我们检查一个例子。$pagenew stdClass();$page->nameHome;$page->status1;现在&#xff0c;假设您有另一个类&#xff0c;它将使用页面对象初始化并在其基础上执行。<?phpclass PageShow {public $curre…

arduino使用oled代码_【惊不?】Arduino改造古董卡西欧计算器为作弊神器

一台朴实无华的计算器&#xff0c;卡西欧牌。看起来和千万学子们所使用的计算器一样&#xff0c;没什么特别的&#xff0c;还带着一些陈旧的使用痕迹。但如果你用磁铁碰一下&#xff1a;咦&#xff0c;简直像打开了探险电影里的神秘机关&#xff0c;右上角的太阳能电池板部分居…

什么都没学到,记录一个鼠标监听事件吧

textField.addMouseListener(new MouseAdapter() { //鼠标在textField中时&#xff0c;改变btnNewButton的文本内容 貌似我的概念是混乱的&#xff0c;用控件乱用哈&#xff0c;哈哈 public void mousePressed(MouseEvent e) { btnNewButton.setText("按下鼠标&qu…

matlab实现id3,MATLAB简单实现ID3

再看《MATLAB数据分析与挖掘实战》&#xff0c;简单总结下今天看到的经典的决策树算法——ID3.ID3&#xff1a;在决策树的各级节点上&#xff0c;使用信息增益的方法作为属性的选择标准&#xff0c;来帮助确定生成每个节点时所应采取的合适属性。关于信息增益&#xff0c;知乎上…

python字符串数组_python将字符串转换成数组的方法

Python这篇文章主要介绍了Python __setattr__、 __getattr__、 __delattr__、__call__用法示例,本文分别对这几个魔法方法做了讲解,需要的朋友可以参考下 ... junjie4882019-11-22 Python这篇文章主要介绍了Python实现list反转的方法,实例总结了关于list的各种较为常见的操作技…