我正在尝试编写一个简单的程序,要求用户从循环中的菜单中进行选择。 我使用getchar()来获取输入,但是我注意到当我输入一个字符并按下'Enter'时,程序会产生两个循环(好像我按两次),一个char作为输入,另一个作为'Enter'作为输入。
我该如何解决这个问题?
答案 0 :(得分:3)
您需要阅读有关规范与非规范输入的内容。以下Stack Overflow问题解决了这个问题:
答案 1 :(得分:2)
在getchar()
:P
getchar()
答案 2 :(得分:2)
最简单的方法是将输入键过滤为getchar
char c = (char)getchar();
if ( c != '\n' ) {
...
}
答案 3 :(得分:2)
getchar()
返回输入缓冲区中的第一个字符,并将其从输入缓冲区中删除。但是其他字符仍然在输入缓冲区中(在您的示例中为\n
)。在再次调用getchar()
之前,您需要清除输入缓冲区:
void clearInputBuffer() // works only if the input buffer is not empty
{
do
{
c = getchar();
} while (c != '\n' && c != EOF);
}
答案 4 :(得分:1)
怎么样
#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;
}
答案 5 :(得分:1)
你有点回答了自己的问题;你必须以某种方式处理换行符。
有几种选择。如果您的菜单选项编号为,则可以使用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中交互式输入处理的精彩世界。