对Linux命令od -tc -tx1的C语言程序实现myod-优化版
導(dǎo)語(yǔ)
自編od C語(yǔ)言實(shí)現(xiàn)版名為myod
上個(gè)星期有一個(gè)初代版,鏈接- myod原版
這星期的課上要求實(shí)現(xiàn)myod-系統(tǒng)調(diào)用版本,要求如下
1 參考教材第十章內(nèi)容
2 用Linux IO相關(guān)系統(tǒng)調(diào)用編寫myod.c 用myod XXX實(shí)現(xiàn)Linux下od -tx -tc XXX的功能,注意XXX是文件名,通過(guò)命令行傳入,不要讓用戶輸入文件名
3.不要把代碼都寫入main函數(shù)中
4.要分模塊,不要把代碼都寫入一個(gè).c中
5 提交測(cè)試代碼和運(yùn)行結(jié)果截圖, 提交調(diào)試過(guò)程截圖,要全屏,包含自己的學(xué)號(hào)信息
程序思路
結(jié)構(gòu)
- 判定命令行輸入是否正確,錯(cuò)誤則報(bào)錯(cuò)退出。
對(duì)文件進(jìn)行錄入并存入字符數(shù)組str[]
相關(guān)函數(shù)及頭文件
| open() | #include <sys/types.h>;#include <sys/stat.h>;#include <fcntl.h> |
| read() | #include <unistd.h> |
- 輸出八位表示的累計(jì)字符
- 輸出最多十六個(gè)為一組的文本
- 輸出該組文本各字符的ASCII碼
- 對(duì)于每行最多處理16個(gè)字符,我使用的是for循環(huán)和一個(gè)計(jì)數(shù)函數(shù)count共同把控
變量說(shuō)明
char str[BUFFERSIZE];存整個(gè)文本的字符串
int LJ;已累計(jì)表示了多少各字符
int SY;還剩下多少字符沒(méi)有表示
int tSY,Dan;tSY其實(shí)是SY,但是為了分模塊處理便于我自己的理解便改了個(gè)名稱,Dan是單次表示字符個(gè)數(shù),和tSY組合使用
int tx[8];char tx2[8];用于表示八位十六進(jìn)制累計(jì)數(shù)字和ASCII碼十六進(jìn)制表示
補(bǔ)充知識(shí)點(diǎn)
- read()在Linux C下,可以直接在終端用man查看,或者下載中文的man幫助文檔,如果懶得翻可以打開該鏈接—— read()
- open()同理—— 打開文件open()函數(shù)的使用方法詳解--C語(yǔ)言函數(shù)
perror()同理——perror; perror 的用法
codeblocks整理代碼:Plugins->Source code formatter(Astyle)
優(yōu)化過(guò)程
代碼對(duì)比
嫌棄版
#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(" ");//累計(jì)字符輸出完畢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("指令輸入錯(cuò)誤\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("字符數(shù)太大,超出限制\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;} }優(yōu)化版
#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("輸入格式錯(cuò)誤");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(" ");//累計(jì)字符輸出完畢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[])//十進(jìn)制轉(zhuǎn)十六進(jìn)制,但此時(shí)仍用int存儲(chǔ) {if(H>536870911){printf("字符數(shù)太大,超出限制\n");exit (0);}int i=7;for(; i>0;){tx[i] = H%16;H = H/16;i--;} } char intToChar(int t)//十六進(jìn)制,把int[]轉(zhuǎn)為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)//計(jì)數(shù)并判定是否終止 {*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"); }改造過(guò)程
1.把沒(méi)來(lái)得及刪掉的用指針打開文件的那段fp = fopen(argv[4],"r"等刪掉,有open就可以了
2.修改自編函數(shù)名稱。當(dāng)我回來(lái)再看代碼時(shí)原先的名稱確實(shí)無(wú)法提醒我到底它要做什么,(捂臉),所以組合型名稱按照小駝峰式,單個(gè)詞函數(shù)名用了首字母大寫的方式,多謝老師指導(dǎo)與提醒~
3.判定命令行輸入條件時(shí)取消那么多if,直接用“|”符號(hào)來(lái)限定選擇條件
if((strcmp(argv[1], "od")!=0)|(strcmp(argv[3], "-tc")!=0)|(strcmp(argv[2], "-tx")!=0))4.將存文本的字符大小用宏定義BUFFERSIZE,提高程序的可讀性與可維護(hù)性。解釋:比如我想存一個(gè)10000的文本,但是之前的str[]只有1000,所以我只需要把define那里的BUFFERSIZE改掉,后面的就不用改了,否則還得滿篇找1000改10000,這個(gè)程序短,所以還不覺(jué)得有什么,但是程序如果很大很復(fù)雜,這種情況不僅維護(hù)的人不好讀懂代碼,而且容易改漏。
5.使用perror()函數(shù),添加報(bào)錯(cuò)功能。
6.將計(jì)數(shù)和輸出ASCII碼的功能從主函數(shù)中分離出來(lái)成為自編函數(shù),使主程序顯得不那么臃腫,更好讀懂。
7.修改了一個(gè)程序上的錯(cuò)誤
for(i2=0; i2<8; i2++){if(tx2[i2]!='0')printf("%c",tx2[i2]);}這個(gè)輸出會(huì)把所有0給抹掉,也是優(yōu)化的時(shí)候才發(fā)現(xiàn)這個(gè)錯(cuò)誤(捂臉)
修改為:
for(i2=0; i2<8; i2++){if(tx2[i2]!='0')break;}for(;i2<8;i2++)printf("%c",tx2[i2]);代碼鏈接
myod嫌棄版(合體)
myod優(yōu)化版(合體)
myod優(yōu)化版(模塊化)
一陣瞎逼逼
第一個(gè)版本我本來(lái)就實(shí)現(xiàn)了命令行調(diào)用,并且并未只寫在一個(gè)main函數(shù)里,就只需要改兩個(gè)函數(shù)就可以了。當(dāng)時(shí)課上電腦不知道被我改了哪里,找不到網(wǎng)絡(luò)的開關(guān)……慌慌地改了代碼交了,覺(jué)得代碼還是有點(diǎn)丑,想著怎么再改改,眼瞎也沒(méi)看到還有展開項(xiàng)-提交代碼……
看到老師對(duì)之前博客的評(píng)論,越看我的代碼越覺(jué)得……好嫌棄,確實(shí)需要好好改一改。于是真的有不少地方可以改……就有了對(duì)二代版的優(yōu)化版。
之所以單開一篇博客是為了方便我日后記不到了好查找資料。是的,作為一個(gè)暑假之后就忘了放在學(xué)校電腦的開機(jī)密碼的人真的不能對(duì)自己的記憶力多有信心。以后可能會(huì)在自己的博客里記錄一些非常簡(jiǎn)單的知識(shí)。反正最終都會(huì)忘掉的,不如讓再次自學(xué)的時(shí)候能輕松高效一些。
轉(zhuǎn)載于:https://www.cnblogs.com/GDDFZ/p/7656052.html
總結(jié)
以上是生活随笔為你收集整理的对Linux命令od -tc -tx1的C语言程序实现myod-优化版的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: bzoj3631: [JLOI2014]
- 下一篇: MPI对道路车辆情况的Nagel-Sch