1.基本信息
函數原型:
int scanf( char *format, args, ...);
函數返回值:
? ? ? ?讀入并賦給args的數據個數。遇到文件結束返回EOF,出錯返回0。
函數功能:
? ? ? ?scanf函數是格式化輸入函數,它從標準輸入設備(鍵盤)讀取輸入的信息。按format指定的格式輸入數據給args所指向的內存單元。
調用格式:
? ? ? ?scanf("格式控制字符串",地址表);
int a, b; scanf("%d%d",&a,&b);//輸入10 12
當中格式控制串由三類字符構成:格式化說明符、空白符、非空白符
1 格式化說明符
? ? ?%c ? ?讀入一個字符 ? ? ? ? ? ? ? ? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ?%d ? ?讀入十進制整數 ? ? ? ? ? ? ? ??
? ? ?%f ? ? 讀入一個浮點數 ? ? ? ? ? ? ? ?
? ? ?%o ? ?讀入一個八進制整數 ? ? ? ?
? ? ?%x ? ? 讀入十六進制整數??
? ? ?%s ? ?讀入一個字符串?
? ? ?%p ? ?讀入一個指針
? ? ?%[] ? ?掃描字符集合,輸入的字符屬于方括號內字符串中某個字符。則提取該字符,否則結束提取
? ? ?%[^] ??掃描字符集合。輸入的字符屬于屬于方括號內字符串中的某個字符,結束提取
2 空白字符
? ? ? 空白字符會使scanf()函數在讀取操作時略去輸入中的一個或多個空白字符,空白字符能夠是space,tab,newline,直到第一個非空白字符出現為止。
之所以被稱為空白字符是由于它們被打印出來時,在頁面上出現的是空白而不是各種記號。
3 非空白字符
? ? ? ?非空白字符會使scanf()函數在讀取時剔除與之同樣的非空白字符。
2. scanf函數的注意事項
? ? ? ? 1. scanf函數中"格式控制"的后面應該是變量地址。
? ? ? ? 2. 假設在“格式控制”字符串中除了格式說明符還有其他字符。則在輸入數據時在相應的位置輸入與之同樣的字符。
? ? ? ? 3. 在用“%c”格式輸入字符時。空白字符(space,tab,newline)和“轉義字符”都作為有效字符輸入。
? ? ? ? 4.?在用“%s”格式輸入字符時,輸入的字符串中含有空白字符(space,tab,newline)。字符串讀取結束。
? ? ? ? 5. 在輸入數據時。遇到下面情況時覺得該數據結束。
? ? ? ? ? ? ?(1) 遇到space。newline,Tab鍵;
? ? ? ? ? ? ?(2) 按指定的寬度輸入;
? ? ? ? ? ? ?(3) 遇到非法輸入;
3 清除鍵盤緩沖區
? ? ? ?鍵盤緩沖區,是計算機輸入過程重要環節。它是一個環形隊列。用來暫時保存從鍵盤輸入的字符。共32字節。
補充說明:
? ? ? ?‘Enter回車鍵’包括1個字符是‘\r’’;
方法1:
int c; while ( ( c = getchar() ) != '\n' && c!= EOF) {; }
? ? ? ?不停的使用getchar()獲取緩沖區字符,直到獲取的字符是換行符'\n'或文件結尾EOF為止,這種方法能夠完美清除輸入緩沖區,而且具備可移植性。
方法2:
刷新標準輸入緩沖區,也就是丟棄緩沖區中的內容。(非標準)fflush( stdin );
4 ?錯誤案例分析
4.1 參數輸入不匹配
int data = -1;while (1){printf("1:\n2:\n3:\n4:\n0:\ninput sever:");scanf("%d",&data);//輸入不是整數data值不改變switch (data){case 1: printf("1\n");break;case 2: printf("2\n");break;case 3: printf("4\n");break;case 0: break;default: printf("default\n");}if (data == 0){break;}}//end of while
問題:
? ? ? ?當不小心輸入了一個字符。而不是數據時。程序進入死循環。不斷輸入printf函數的內容。
分析:
? ? ? 因為scanf("%d",&data)要求參數是個整數,而實際輸入卻為字符,參數不匹配scanf結束data的輸入。
函數繼續運行。
當再次運行到scanf函數時。此時輸入緩沖區中有內容。直接從緩存中讀取不再等待人為輸入。故出現死循環。屏幕不再有等待輸入提示。
辦法:
? ? ? ?在scanf函數后加入fflush(stdin)就能夠解決這個問題了。
由于每次輸入數據時緩沖區都被刷新,每次都會等待輸入。
4.2 scanf輸入中不能有空格的問題
char str[80];scanf("%s",str);printf("str = %s\n", str);
問題:
? ? ? ?當輸入的字符中有空格時,輸出不完整。
分析:
? ? ? %s格式字符遇到空格時結束讀取。興許的字符不再讀取儲存。
辦法1:
? ? ? ?scanf函數改寫為:scanf("%[^'\n']",str);
辦法2:
? ? ? ? 使用gets函數,關于gets函數見:gets()函數具體解釋與缺陷
4.3 %c和緩沖區問題
char str[5];for(int i = 0; i < 4; i++) {scanf( "%c",&str[i]); }str[4] = '\0'; printf("str:%s\n",str);
問題:
? ? ? 當輸入a回車b回車。函數運行結束。
分析:
? ? ?因為scanf按%c格式輸入,當輸入a并按回車時輸入緩沖區中的內容是'a'和'\r',分別給了str[0]和str[1]。相同輸入b時也是如此。剛好4個字符結束輸入。
str字符數組的內容各自是'a'、'\r'、'b'、'\r'、'\0'。
辦法1:
? ? ? ?在scanf函數后面加入語句:fflush(stdin);
辦法2:
? ? ? ?使用gets函數。