《C Primer Plus(第6版)中文版》 第8章 字元I/O和輸入驗證
阿新 • • 發佈:2021-01-23
對標題和序號有稍加修改。
8.1 緩衝區
輸入分為無緩衝輸入和緩衝輸入。無緩衝輸入即回顯使用者輸入的字元後立即重複列印該字元。緩衝輸入即在按下Enter鍵前不會重複列印輸入的字元。緩衝區(buffer)是儲存使用者輸入字元的臨時儲存區,在按下Enter鍵後程序才能使用輸入的字元。緩衝區大小取決於系統,常見大小為512位元組或4096位元組。
緩衝分為完全緩衝I/O和行緩衝I/O。完全緩衝I/O指當緩衝區被填滿時才重新整理緩衝區,即把資料傳送到螢幕或檔案中,常用於檔案輸入。行緩衝I/O指遇到換行符時重新整理緩衝區,常用於鍵盤輸入。
C標準明確規定了當緩衝區滿、遇到換行字元或需要輸入的時候重新整理緩衝區。舊式編譯器遇到scanf()
\n
重新整理緩衝區。
ANSI C和後續C標準都規定輸入是緩衝的,ANSI沒有提供無緩衝的標準方式。
8.2 結束鍵盤輸入
8.2.1 檔案、流和鍵盤輸入
檔案(file)是儲存器中儲存資訊的區域。較低層面,C用底層I/O(lower-level I/O)處理檔案。較高層面,用標準I/O包(standard I/O package)處理檔案。
流(stream)是一個實際輸入或輸出對映的理想化資料流。C通過處理流來處理檔案,開啟檔案就是將流與檔案關聯,讀寫通過流來完成。
stdin流表示鍵盤輸入,stdout表示螢幕輸出。標準I/O成員getchar()
putchar()
、scanf()
和printf()
用來處理兩個流。
8.2.2 檔案結尾
檢測檔案結尾的兩個方法:
- 使用特殊標記,例如Ctrl+Z。
- 儲存檔案大小的資訊。
C語言輸入函式內建了檔案結尾檢測器,當輸入函式讀取檔案檢測到結尾時就返回EOF(end of file),它被定義在stdio.h
中。
#define EOF (-1)
示例程式:
#include<stdio.h>
int main(void)
{
int ch;
while ((ch=getchar())!=EOF)
putchar(ch);
return 0;
}
輸出結果:
abcdefg
abcdefg
123
123
[email protected]#$
[email protected]#$
^Z
每次按Enter都會重新整理緩衝區,將輸入的內容在下一行打印出來,直至在新行中鍵入Ctrl+Z,才結束鍵盤輸入。
8.3 建立更友好的使用者介面
8.3.1 使用緩衝輸入
示例程式:
/*猜數字*/
#include<stdio.h>
int main(void)
{
int guess=1;
char response; //儲存響應字元,每行第一個字元
printf("Pick an integer from 1 to 100.I will try to guess it.\n");
printf("Respond with y if my guess is right"
" and with n if it is wrong.\n");
printf("Uh...is your number %d?\n",guess);
while ((response=getchar())!='y') //每次只讀每行第一個字元
{
if (response=='n')
printf("Well,then,is it %d?\n",++guess);
else
printf("Sorry, I understand only y or n,"
" press n to continue.\n");
/*處理讀取每行第一個字元後的所有輸入字元,包括回車產生的換行符*/
while (getchar()!='\n')
continue;
}
printf("Done!\n");
return 0;
}
輸出結果:
Pick an integer from 1 to 100.I will try to guess it.
Respond with y if my guess is right and with n if it is wrong.
Uh...is your number 1?
n
Well,then,is it 2?
no sir
Well,then,is it 3?
forget it!
Sorry, I understand only y or n, press n to continue.
n
Well,then,is it 4?
y
Done!
8.3.2 混合數值和字元輸入
示例程式:
/*按指定行列列印字元*/
#include<stdio.h>
void display(char cr, int lines, int width); /*函式原型*/
int main(void)
{
int ch; /*待列印字元*/
int rows,cols; /*行數和列數*/
printf("Enter a character and two integers:\n");
while ((ch=getchar())!=EOF) /*EOF結束鍵盤輸入*/
{
/*沒有正確讀取行和列數就退出迴圈*/
if (scanf("%d %d",&rows,&cols)!=2)
break;
/*正確讀取行和列數就呼叫函式*/
display(ch,rows,cols);
/*跳過輸入中剩餘的多餘項*/
while (getchar()!='\n')
continue;
printf("Enter another character and two integers:\n"
"Press Ctrl+Z to quit.\n");
}
printf("Done!\n");
return 0;
}
/*函式定義*/
void display(char cr, int lines, int width)
{
int row,col;
for (row = 1; row <= lines; row++)
{
for (col = 1; col <= width; col++)
putchar(cr);
putchar('\n');
}
}
輸出結果:
Enter a character and two integers:
c 1 2
cc
Enter another character and two integers:
Press Ctrl+Z to quit.
! 3 6
!!!!!!
!!!!!!
!!!!!!
Enter another character and two integers:
Press Ctrl+Z to quit.
^Z
Done!