1. 程式人生 > 其它 >《C Primer Plus(第6版)中文版》 第8章 字元I/O和輸入驗證

《C Primer Plus(第6版)中文版》 第8章 字元I/O和輸入驗證

技術標籤:C/C++c語言

對標題和序號有稍加修改。

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!