在c上使用getchar()在输入后获得’Enter’

我正在尝试编写一个简单的程序,要求用户从循环中的菜单中进行选择。 我使用getchar()来获取输入,但是我注意到当我输入一个字符并按下’Enter’时,程序会产生两个循环(好像我按两次),一个char作为输入,另一个作为’Enter’作为输入。

我该如何解决?

感谢名单。

您需要阅读有关规范与非规范输入的内容。 以下Stack Overflow问题解决了这个问题:

典型-VS-非规范终端输入

getchar()之后添加一个getchar() getchar() :P

getchar()返回输入缓冲区中的第一个字符,并将其从输入缓冲区中删除。 但是其他字符仍在输入缓冲区中(在您的示例中为\n )。 在再次调用getchar()之前,需要清除输入缓冲区:

 void clearInputBuffer() // works only if the input buffer is not empty { do { c = getchar(); } while (c != '\n' && c != EOF); } 

最简单的方法是将enter键过滤为getchar的返回值

 char c = (char)getchar(); if ( c != '\n' ) { ... } 

怎么样

 #include  /*! 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; } 

资源

你有点回答了自己的问题; 你必须以某种方式处理换行符。

有几种选择。 如果菜单选项已编号 ,则可以使用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()将所有输入作为字符串读取,然后根据需要进行解析和validation。

 /** * 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中交互式输入处理的精彩世界。