最近在混合使用 getchar() 和 scanf() 的時候遇到一個坑,現在記錄一下。
代碼中使用 getchar() 處理字符輸入,用 scanf() 處理數字輸入。
getchar() 讀取每個字符,包括空格、制表符和換行符; 而 scanf() 在讀取數字時則會跳過空格、
制表符和換行符。
比如下面這個程序,讀入一個字符和兩個數字,然后根據輸入的兩個數字指定的行數和列數打印該字符。
#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()) != '\n')
{
scanf("%d %d", &rows, &cols);
display(ch, rows, cols);
printf("Enter another character and two integers;\n");
printf("Enter a newline to quit.\n");
}
printf("Bye.\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 newline to quit. 之后就自動退出了。
原來,在輸入了一個字符和兩個數字之后,需要敲一個回車鍵,回車鍵產生了一個換行符。這個換行符不會被例程中的 scanf() 讀取,但它會繼續留在輸入隊列中。當程序運行到下一輪循環的 getchar() 函數時,換行符就會被 getchar() 函數讀取,導致程序直接結束了。
解決方法:可以在循環內部添加如下代碼來消耗輸入隊列中的換行符以及其他多余的字符:
while (getchar() != '\n')
continue;
完整代碼如下:
#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()) != '\n')
{
if (scanf("%d %d", &rows, &cols) != 2)
break;
display(ch, rows, cols);
while (getchar() != '\n')
continue;
printf("Enter another character and two integers;\n");
printf("Enter a newline to quit.\n");
}
printf("Bye.\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'); /* 結束一行並開始新的一行 */
}
}
如發現有不對的地方,歡迎在評論區指出。
