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