我正試圖編寫一個簡單的程序,要求用戶從循環中的菜單中進行選擇。 我使用getchar()來獲取輸入,但是我注意到,當我輸入一個字符並按下'Enter'時,程序會產生兩個循環(就像我按兩次)一個字符作爲輸入,另一個輸入'Enter '作爲輸入。在c上使用getchar()在輸入後得到'Enter'
我該如何解決這個問題?
Thanx。
我正試圖編寫一個簡單的程序,要求用戶從循環中的菜單中進行選擇。 我使用getchar()來獲取輸入,但是我注意到,當我輸入一個字符並按下'Enter'時,程序會產生兩個循環(就像我按兩次)一個字符作爲輸入,另一個輸入'Enter '作爲輸入。在c上使用getchar()在輸入後得到'Enter'
我該如何解決這個問題?
Thanx。
如何
#include <stdio.h>
/*! getline() reads one line from standard input and copies it to line array
* (but no more than max chars).
* It does not place the terminating \n in line array.
* Returns line length, or 0 for empty line, or EOF for end-of-file.
*/
int getline(char line[], int max)
{
int nch = 0;
int c;
max = max - 1; /* leave room for '\0' */
while ((c = getchar()) != EOF) {
if (c == '\n')
break;
if (nch < max) {
line[nch] = c;
nch = nch + 1;
}
}
if (c == EOF && nch == 0)
return EOF;
line[nch] = '\0';
return nch;
}
您需要閱讀有關規範與非規範輸入。下面的堆棧溢出的問題解決了這個:
+1 - 您可以通過使用[tcsetattr()](http:// www)來將終端設置爲原始(非規範)模式。 opengroup.org/onlinepubs/000095399/functions/tcsetattr.html)來操作** termios **結構。 – jschmier 2010-10-19 15:23:23
添加getchar()
的getchar()
後:P
我想這會工作,但它的安靜麻醉。 – SnapDragon 2010-10-20 18:02:50
在某些情況下,用戶會發現自己不得不按兩次返回,這會產生問題。 – Kaitain 2017-05-05 00:00:51
最簡單的方法是從getchar
char c = (char)getchar();
if (c != '\n') {
...
}
濾除進入鍵,返回值
我想你的意思是getchar()?如果這樣getchar()返回int。 – Nyan 2010-10-19 15:41:25
@Nyan,'getchar''確實返回'int',但通過轉換分配給'char'是合法的。參考http://www.cplusplus.com/reference/clibrary/cstdio/getchar/ – JaredPar 2010-10-19 15:51:45
@Jared:是的,但char限於(最終)256個值,並且您需要(最終)257個值來識別** ALL * *字符**和** EOF。這就是爲什麼'getchar()'返回一個int – pmg 2010-10-19 15:54:08
getchar()
返回輸入緩衝區中的第一個字符,並將其從輸入緩衝區中刪除。但其他字符仍在輸入緩衝區中(在您的示例中爲\n
)。你需要再次調用getchar()
之前清除輸入緩衝區:
void clearInputBuffer() // works only if the input buffer is not empty
{
do
{
c = getchar();
} while (c != '\n' && c != EOF);
}
你樣的回答了你自己的問題;你必須以某種方式處理換行符。
有幾種選擇。如果你的菜單選項編號爲,您可以使用scanf()
在一個整數值讀取和交換基礎上認爲:
printf("Pick an option: ");
fflush(stdout);
scanf("%d", &option);
switch(option)
{
case 0 : do_something(); break;
case 1 : do_something_else(); break;
...
default: bad_option(); break;
}
這個方案的優點是%d
轉換符跳過任何前導空格,包括換行符,所以你不必擔心任何未讀的\n
堵塞輸入流(實際上,大多數轉換說明符跳過前導空格; %c
沒有,使其表現很像getchar()
)。
此選項的缺點是,如果有人在其輸入中輸入一個非數字字符,它將不會被%d
轉換說明符讀取,並會一直停留在輸入流中,直到調用getchar()
或scanf()
與%s
或%c
轉換說明符。
更好的選擇是將所有輸入作爲字符字符串讀取,使用fgets()
,然後根據需要進行解析和驗證。
/**
* Prints a prompt to stdout and reads an input response, writing
* the input value to option.
*
* @param prompt [in] - prompt written to stdout
* @param option [out] - option entered by user
*
* @return - 1 on success, 0 on failure. If return value is 0, then option
* is not changed.
*/
int getOption(const char *prompt, char *option)
{
char input[3]; // option char + newline + 0 terminator
int result = 0;
printf("%s: ", prompt);
fflush(stdout);
if (fgets(input, sizeof input, stdin))
{
/**
* Search for a newline character in the input buffer; if it's not
* present, then the user entered more characters than the input buffer
* can store. Reject the input, and continue to read from stdin until
* we see a newline character; that way we don't leave junk in the
* input stream to mess up a future read.
*/
char *newline = strchr(input, '\n');
if (!newline)
{
printf("Input string is too long and will be rejected\n");
/**
* Continue reading from stdin until we find the newline
* character
*/
while (!newline && fgets(input, sizeof input, stdin))
newline = strchr(input, '\n');
}
else
{
*option = input[0];
result = 1;
}
}
else
printf("Received error or EOF on read\n");
return result;
}
是的,這是一個愚蠢的菜單選項閱讀很多工作,這就是簡單的版本。歡迎來到C中交互輸入處理的美妙世界。
我不能使用字符串或字符數組(它是一門課程的作品) – SnapDragon 2010-10-20 18:06:31