日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

發(fā)布時間:2025/3/15 linux 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对Linux命令od -tc -tx1的C语言程序实现myod-优化版 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

導(dǎo)語

  • 自編od C語言實現(xiàn)版名為myod

  • 上個星期有一個初代版,鏈接- myod原版

  • 這星期的課上要求實現(xiàn)myod-系統(tǒng)調(diào)用版本,要求如下

    1 參考教材第十章內(nèi)容

    2 用Linux IO相關(guān)系統(tǒng)調(diào)用編寫myod.c 用myod XXX實現(xiàn)Linux下od -tx -tc XXX的功能,注意XXX是文件名,通過命令行傳入,不要讓用戶輸入文件名

    3.不要把代碼都寫入main函數(shù)中

    4.要分模塊,不要把代碼都寫入一個.c中

    5 提交測試代碼和運行結(jié)果截圖, 提交調(diào)試過程截圖,要全屏,包含自己的學(xué)號信息

程序思路

結(jié)構(gòu)

  • 判定命令行輸入是否正確,錯誤則報錯退出。
  • 對文件進行錄入并存入字符數(shù)組str[]

    相關(guān)函數(shù)及頭文件

函數(shù)頭文件
open()#include <sys/types.h>;#include <sys/stat.h>;#include <fcntl.h>
read()#include <unistd.h>
  • 輸出八位表示的累計字符
  • 輸出最多十六個為一組的文本
  • 輸出該組文本各字符的ASCII碼
  • 對于每行最多處理16個字符,我使用的是for循環(huán)和一個計數(shù)函數(shù)count共同把控

變量說明

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

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

int SY;還剩下多少字符沒有表示

int tSY,Dan;tSY其實是SY,但是為了分模塊處理便于我自己的理解便改了個名稱,Dan是單次表示字符個數(shù),和tSY組合使用

int tx[8];char tx2[8];用于表示八位十六進制累計數(shù)字和ASCII碼十六進制表示

補充知識點

  • read()在Linux C下,可以直接在終端用man查看,或者下載中文的man幫助文檔,如果懶得翻可以打開該鏈接—— read()
  • open()同理—— 打開文件open()函數(shù)的使用方法詳解--C語言函數(shù)
  • perror()同理——perror; perror 的用法

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

優(yōu)化過程

代碼對比

嫌棄版

#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("字符數(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("輸入格式錯誤");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[])//十進制轉(zhuǎn)十六進制,但此時仍用int存儲 {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)//十六進制,把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)//計數(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"); }

改造過程

1.把沒來得及刪掉的用指針打開文件的那段fp = fopen(argv[4],"r"等刪掉,有open就可以了

2.修改自編函數(shù)名稱。當(dāng)我回來再看代碼時原先的名稱確實無法提醒我到底它要做什么,(捂臉),所以組合型名稱按照小駝峰式,單個詞函數(shù)名用了首字母大寫的方式,多謝老師指導(dǎo)與提醒~

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,這個程序短,所以還不覺得有什么,但是程序如果很大很復(fù)雜,這種情況不僅維護的人不好讀懂代碼,而且容易改漏。

5.使用perror()函數(shù),添加報錯功能。

6.將計數(shù)和輸出ASCII碼的功能從主函數(shù)中分離出來成為自編函數(shù),使主程序顯得不那么臃腫,更好讀懂。

7.修改了一個程序上的錯誤

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

這個輸出會把所有0給抹掉,也是優(yōu)化的時候才發(fā)現(xiàn)這個錯誤(捂臉)

修改為:

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)化版(模塊化)

一陣瞎逼逼

第一個版本我本來就實現(xiàn)了命令行調(diào)用,并且并未只寫在一個main函數(shù)里,就只需要改兩個函數(shù)就可以了。當(dāng)時課上電腦不知道被我改了哪里,找不到網(wǎng)絡(luò)的開關(guān)……慌慌地改了代碼交了,覺得代碼還是有點丑,想著怎么再改改,眼瞎也沒看到還有展開項-提交代碼……

看到老師對之前博客的評論,越看我的代碼越覺得……好嫌棄,確實需要好好改一改。于是真的有不少地方可以改……就有了對二代版的優(yōu)化版。

之所以單開一篇博客是為了方便我日后記不到了好查找資料。是的,作為一個暑假之后就忘了放在學(xué)校電腦的開機密碼的人真的不能對自己的記憶力多有信心。以后可能會在自己的博客里記錄一些非常簡單的知識。反正最終都會忘掉的,不如讓再次自學(xué)的時候能輕松高效一些。

轉(zhuǎn)載于:https://www.cnblogs.com/GDDFZ/p/7656052.html

總結(jié)

以上是生活随笔為你收集整理的对Linux命令od -tc -tx1的C语言程序实现myod-优化版的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。