最近一直看這本書,發現裡面的習題真的太經典了,很多習題看是簡單,但是要真正的做好,還真需要費很大的事。
【習題1.10】
這裡我們先根據習題1.9的套路給出一個程式。
/* 本程式用來將輸入的定位字元、退格符顯式輸出,將反斜線以"\\"的形式輸出*/#include <stdio.h>int main(int argc,char* argv[]){ short int Input; while(EOF !=(Input=getchar())) { switch(Input) { case '\t': putchar('\\'); putchar('t'); break; case '\b': putchar('\\'); putchar('b'); break; case '\\': putchar('\\'); putchar('\\'); break; default: putchar(Input); } } return 0;}
程式執行情況如下所示:
這裡有一個問題需要說明: 就是如何在終端輸入'\b'字元。可以發現利用上面的程式我們無法輸入退格字元。
原因是: getchar()函數是從輸入緩衝區讀入字元的,而輸入緩衝機制裡面,Backspace鍵會將輸入緩衝區棧頂的字元出棧,因此具有輸入緩衝機制
的庫函數都不能實現 '\b' 字元的有效輸入。
解決方案是: 不通過輸入緩衝區輸入字元。在庫函數中getch()函數可以達到這個目的。
但是這樣有一個新的問題,那就是getch()函數不能回顯,還有就是getch()函數不能像getchar()函數一樣輸入Ctrl + Z 組合;
這裡就需要進行處理輸入回顯的問題。
要點:這裡需要說明一點,getch函數不是ANSI標準庫裡面的函數,標準庫函數裡面定義的是
getc()函數。標準庫裡面有些符號是定義的宏,而且具有同名的函數。
例如:getchar() 既有宏、也有函數。
題外話:
這裡我們輸入字元的時候,在換行的時候就輸出了,有時可能需要一直輸入,直到輸入某個特定的字元才輸出。這就需要
修改了,那需要怎麼辦呢?
我這裡藉助鏈表實現一直儲存,然後整個的輸入。
鏈表的建立、插入、刪除、尋找和顯示。
/* 本程式用來測試鏈表的基本操作*/#include <stdio.h>#include <stdlib.h>typedef struct node{ char chInput; struct node* next;}NODE;void CreateList(NODE* head);void EchoList(NODE* head);void InsertNode(NODE* head,char chPosition,char chElement);void DeleteNode(NODE* head,char chElement);NODE* SearchNode(NODE* head,char chElement);int main(int argc,char* argv[],char* env[]){ NODE* head; NODE* FindNode; char chInput; head=(NODE *)malloc(sizeof(NODE)); CreateList(head); EchoList(head); puts("Enter the charecter you want to search:"); chInput=getchar(); FindNode=SearchNode(head,chInput); if(NULL==FindNode) puts("Can not find the element"); else { putchar(FindNode->chInput ); putchar('\n'); DeleteNode(head,chInput); EchoList(head); } getchar(); getchar(); return 0;}void CreateList(NODE* head){ NODE* end; NODE* temp; short int chInput; end=head; while((chInput=getchar())!=EOF) { end->chInput =chInput; temp=(NODE *)malloc(sizeof(NODE)); temp->next =NULL; end->next =temp; end=temp; }}void EchoList(NODE *head){ NODE* temp; temp=head; while(temp->next != NULL) { putchar(temp->chInput); temp=temp->next ; }}NODE* SearchNode(NODE* head,char chElement){ NODE* temp; temp=head; //處理只有一個節點的情況 if(temp->next ==NULL) { if(temp->chInput ==chElement) return temp; else return NULL; } while(temp->next != NULL) { if(chElement == temp->chInput) break; else temp=temp->next ; } return temp;}void InsertNode(NODE* head,char chPosition,char chElement){ NODE* temp; NODE* NewNode; temp=SearchNode(head,chPosition); NewNode=(NODE *)malloc(sizeof(NODE)); NewNode->chInput=chElement; NewNode->next =temp->next ; temp->next =NewNode;}void DeleteNode(NODE* head,char chElement){ NODE* temp; NODE* DeNode; temp=head; DeNode=head; if(head->chInput==chElement) { head=head->next; temp->next =NULL; free(temp); } else { while(DeNode->next!=NULL) { if(DeNode->next ->chInput ==chElement) { temp=DeNode->next ; DeNode->next =DeNode->next->next ; temp->next =NULL; free(temp); } DeNode=DeNode->next ; } } }
如果要實現多行輸入後,然後集中輸出,僅需要將上面的Echo函數修改即可實現;思路也很簡單,當需要輸出指定字元時則
單獨處理即可,否則就依次輸出即可。
void EchoList(NODE *head){ NODE* temp; temp=head; while(temp->next != NULL) { switch(temp->chInput) { case '\t': putchar('\\'); putchar('t'); break; case '\b': putchar('\\'); putchar('b'); break; case '\\': putchar('\\'); putchar('\\'); break; default: putchar(Input); } temp=temp->next ; }}
這次就說這麼多吧。