一 分析
使用函數getc(stdin)可以從鍵盤獲得用戶輸入
二 實現
1 簡單的輸入回顯
代碼
#include <stdio.h> #include <stdlib.h> int main() { char input; while(1) { printf("Enter:"); input = getc(stdin); printf("You enter:%c\n",input); } }
理想輸出:
Enter:a
You enter:a
實際輸出1
Enter:1 You enter:1 Enter:You enter:
實際輸出2
Enter:asd
You enter:a
Enter:You enter:s
Enter:You enter:d
Enter:You enter:
2 getc() 從緩存中讀取字符
getc()函數從緩存中讀取字符,這就導致了1中理想和實際輸出的差異。
從緩存讀取字符的含義:用戶在終端輸入字符的時侯,終端並不知道用戶輸入了些什么,直到用戶輸入回車字符,終端將回車字符輸入前的所有字符及回車字符本身存入緩存等待其他函數調用。此時若執行一次getc就從緩存中取出一個字符,並將該字符從緩存中清除。getc函數可以循環讀取,直到緩存中所有字符,包括回車符都被讀取完畢為止。若緩存被讀完,getc返回EOF。
對於1的代碼來說,用戶輸入字符a前后發生了如下事情:
(1)執行 printf("Enter:"); 界面輸出提示符“Enter:”
(2)執行 input = getc(stdin); 等待用戶輸入
(3)用戶輸入字符'a', 緩存中包含“a”
(4)用戶輸入‘回車’, 緩存中包含“a、回車”,執行下一步
注意,input只能讀取1個字符'a';緩存中a被讀出,現在只剩“回車符”
(5)執行 printf("You enter:%c\n",input); 界面輸出緩存中第一個字符 "You enter:a"
(6)程序回到一開始,執行printf("Enter:"); 在下一行輸出提示符“Enter:”
(7)執行input = getc(stdin); 因為現在緩存中還有個“回車符”呢,所以程序認為用戶已輸入,input=回車,緩存被清空
(8)執行 printf("You enter:%c\n",input); 界面輸出"You enter:"並換行
(9)程序回到一開始,執行printf("Enter:"); 在下一行輸出提示符“Enter:”
(10)執行input = getc(stdin); 由於緩存是空的,所以程序執行到這里就等待用戶輸入。
3 如何讀取完整的用戶輸入並輸出,做一個getline
從2中我們可以看到,執行getc后,程序等待用戶輸入,用戶在這里可以輸入刪減任何字符,直到用戶輸入回車符后,程序將用戶全部的輸入放入緩存,但是,此時getc只能返回緩存中的第一個字符,再次執行getc,返回第二個字符,一直到返回‘回車符’后結束,再次執行getc函數,則程序等待用戶輸入。
(在Ubuntu上實驗發現,getc函數在獲取用戶輸入時,緩存讀取完畢並沒有返回EOF,獲得回車符之后,再次支持getc直接進入等待用戶輸入,所以我們只能使用回車符來判斷用戶的全部輸入已讀完。)
1)如何做一個getline
使用getc如何做一個一次返回全部用戶輸入的getline呢?大概過程如下:
(1)先是有個大循環
(2)循環里先執行getc等待用戶輸入
(3)用戶輸入完成后,getc返回第一個字符
(4)判斷該字符是否為‘回車符’,是的話就結束循環,返回保存的字符串,否的話執行下一步
(5)將該字符保存,返回第二步,如果緩存里還有東西沒輸出,那就不會等用戶輸入,getc直接返回下一個字符
流程圖:
2)getline的代碼
#include <stdio.h> #include <stdlib.h> #include <string.h> int getsline(char *result) { int point = 0; int word; while(1) { word = getc(stdin);//等待用戶輸入或從緩存中讀一個字符 if(word != '\n')//讀到回車符就認為一行指令被讀完了 { *result = word;//記錄這個字符 result ++; point ++; } else { result = '\0';//給指針末尾添加一個結束符 result = result - point;//讓指針指回字符串的頭 return 0; } } } int main() { char *line; line = malloc(100); getsline(line); printf("You enter:%s\n",line); return 0; }