最近一直看这本书,发现里面的习题真的太经典了,很多习题看是简单,但是要真正的做好,还真需要费很大的事。
【习题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 ; } }
这次就说这么多吧。