实现more
發現還是基本功要扎實才行,重新學習linux, 做好讀書筆記
? ? 程序要訪問設備,必須要通過內核才能實現。 編寫普通程序可以認為程序是直接訪問鍵盤,顯示器等。但是在進行inux系統編程的時候,就必須知道內核提供了哪些服務,如何使用它們。系統有哪些資源和設備,應該要如何操作。
本次編寫的more,按照3個問題來實現
1. more能做什么
2. more是如何實現的
3. 能不能自己編寫一個more
?
1. more能做什么?
more,cat,less,pg都是屬于查看文件內容的。 cat是整個一期顯示。more是當文件很多的時候,分屏顯示。
more有3種用法:
$more filename ? ? ?//顯示filename的內容
$command | more ?//將command命令的輸出分頁顯示
$more < filename ? //more的輸入被重定向為filename
?
2. more是如何實現的
? A 顯示24行的輸出
? B 左下角顯示more?
? C 用戶輸入 回車,空格,或者q,分別代表下一頁,下一行和退出
?
3. 能不能自己編寫一個more。
? ? 按照2的思路,完全可以用c寫一個簡單的more
偽代碼如下:
do_more(FIIE):
???????? 循環讀取文件:
顯示24行的內容
獲取more的輸入命令
根據輸入命令,繼續處理顯示內容
?
獲取more的輸入命令:
???????? Enter-> 返回讀取下一行請求
空格 -> 返回讀取下一頁請求
q? ??-> 返回 退出
?
#include<stdio.h>#define LINELEN 512 #define PAGELEN 24 #define QUIT -1 #define NEXTLINE 1int get_cmd_more(); void do_more(FILE* fp);int main(int ac, char* av[]){FILE * fp= NULL;if(ac == 1){do_more(stdin);}else{//如果輸入多個文件,依次打開文件while (--ac) {if(fp = fopen(*++av,"r")){do_more(fp);}else{exit(1);}}//end while }return 0; }//do_more(FIIE): void do_more(FILE* fp){char line[LINELEN];int lineCount =0;int cmdLineNum =0;// 循環讀取文件,fgets每次讀取一行,每行512個字節:while (fgets(line,LINELEN,fp)) {//讀一行顯示一行if( fputs(line,stdout) == EOF)exit(1);//當讀取行數滿足24行后,顯示more?if(lineCount == PAGELEN){//獲取more的輸入命令cmdLineNum = get_cmd_more();//根據輸入命令,繼續處理顯示內容if(cmdLineNum == QUIT)break;lineCount -= cmdLineNum;}//這行的數據處理完后,數量+1lineCount++;}//end while }//獲取more的輸入命令: int get_cmd_more(){// Enter-> 返回讀取下一行請求//空格 -> 返回讀取下一頁請求//q -> 返回 退出int getCmd=0;printf("\033[7m more?\033[m");getCmd = getchar();switch (getCmd) {case '\n':return NEXTLINE;case ' ':return PAGELEN;case 'q':return QUIT;default:return 0;}; }?
?
在main中檢查了參數, 如果沒有參數,就從標準輸入中讀取,運行程序ls | myMore,發現是全部數據一次性輸出的,沒有出現期望的分頁。
當more 讀入第24行后,打印了more?然后是用getchar,從標準輸入中讀入數據,但是我們現在重定向到ls的標準輸出了。 所以more現在至少有2個輸入源。我們使用鍵盤和顯示器的設備描述符,對輸入和輸出進行抽象, 更新代碼如下
#include<stdio.h>#define LINELEN 512 #define PAGELEN 24 #define QUIT -1 #define NEXTLINE 1int get_cmd_more(FILE* ); void do_more(FILE* fp);int main(int ac, char* av[]){FILE * fp= NULL;if(ac == 1){do_more(stdin);}else{//如果輸入多個文件,依次打開文件while (--ac) {if(fp = fopen(*++av,"r")){do_more(fp);}else{exit(1);}}//end while }return 0; }//do_more(FIIE): void do_more(FILE* fp){char line[LINELEN];int lineCount =0;int cmdLineNum =0;//開啟鍵盤和顯示器的設備描述文件FILE* fp_tty;fp_tty = fopen("/dev/tty","r");if(!fp_tty)exit(1);// 循環讀取文件,fgets每次讀取一行,每行512個字節:while (fgets(line,LINELEN,fp)) {//讀一行顯示一行if( fputs(line,stdout) == EOF)exit(1);//當讀取行數滿足24行后,顯示more?if(lineCount == PAGELEN){//獲取more的輸入命令cmdLineNum = get_cmd_more(fp_tty);//根據輸入命令,繼續處理顯示內容if(cmdLineNum == QUIT)break;lineCount -= cmdLineNum;}//這行的數據處理完后,數量+1lineCount++;}//end while }//獲取more的輸入命令: int get_cmd_more(FILE* cmd){// Enter-> 返回讀取下一行請求//空格 -> 返回讀取下一頁請求//q -> 返回 退出int getCmd=0;printf("\033[7m more?\033[m");getCmd = getc(cmd);switch (getCmd) {case '\n':return NEXTLINE;case ' ':return PAGELEN;case 'q':return QUIT;default:return 0;}; }基本上一個簡單的more就實現了。
?
轉載于:https://www.cnblogs.com/XiangWei1/p/6720175.html
總結
- 上一篇: 洛谷——1064金明的预算方案————有
- 下一篇: 错误代码: 1054 Unknown c