为什么我的教授使用两个getchar(); 在我们的C程序教程结束时?
对此有什么"更好的方法"?
他正在等待用户输入,以便您可以看到程序的输出,否则它将完成并且输出将不可见(取决于操作系统).拿出来尝试一下.
他希望控制台保持打开状态并等待用户按下一个键.我想要记住,取决于你的教授计划上面的"getchar()".缓冲区中可能仍然存在某些内容,因此他添加了第二个"getchar()".不完全是解决问题的最优雅方式.
编辑:这是一个小例子."scanf()"缓冲区中仍然存在剩余的"\n"如果添加第二个"getchar()",则会得到预期的结果.您必须在"getchar()"之前刷新缓冲区.
#includemain() { int input; scanf("%d", &input); printf("The input is %d\n", input); getchar(); return 0; }
编辑2:这是从这里采取的解决方案.
int c; printf( "Press ENTER to continue... " ); fflush( stdout ); do c = getchar(); while ((c != '\n') && (c != EOF));
最好的方法是不添加任何代码来尝试并保持控制台窗口打开:从控制台窗口直接启动程序.
如果您必须从IDE启动程序并希望程序在用户按下Enter之前不终止,则getchar()
应该执行一个程序.
在用户按下键之后使程序终止的第二个更好的方法是始终确保没有待处理的输入并使用一个getchar()
.
getchar()
我想,你的老师使用2的原因是输入缓冲区中已存在来自先前输入的字符.要使用输入中的所有字符,包括ENTER,这通常是:
int ch; /* ... */ printf("Press Enter"); fflush(stdout); while ((ch = getchar()) != '\n' && ch != EOF) /* void */;
许多初学者认为有必要在他们的代码中放两个 getch
调用的原因是一个单独的调用通常不起作用.
原因是getch
从输入队列中获取下一个键盘输入.不幸的是,只要用户按下键盘上的键,这个队列就会被填充,即使应用程序当时没有等待输入(如果它没有读取整个输入 - 请参阅Lulu的答案).因此,getch
将从输入队列中获取一个字符,而无需等待下一次按键 - 这正是程序员想要的.
当然,在键盘队列中只有一个字符的情况下,这种"解决方案"在很多情况下仍会失败.更好的解决方案是刷新该队列,然后请求下一个字符.不幸的是,据我所知,在C/C++中没有与平台无关的方法.在C++中执行此操作的常规方法(抱歉,我的C有限)看起来像这样:
std::cin.ignore(std::cin.rdbuf()->in_avail());
这只是忽略所有可用输入,有效地清除输入队列.不幸的是,这段代码并不总是有用(出于非常神秘的原因).
为什么我的教授使用两个getchar(); 在我们的C程序教程结束时?
假设你有类似的东西
int main ( void ) { int input; scanf ( "%d", &input ); printf ( "The input is %d.\n", input ); getchar(); getchar(); return 0; }
两个因为scanf
在按下输入之后才会返回,但是输入中的'\n'和输入缓冲区中输入的任何其他字符都会有.
因此,如果您运行上述并输入1234
Enter,程序将在打印后暂停,The input is 1234.
直到您再次按下Enter.第一个getchar
读取'\n'
与第一个相关联Enter.如果您输入其他内容,例如1234
SpaceEnter,程序将不会暂停,因为首先getchar
会读取空格.两个getchar
可能还不够,并且您已经将用于打印响应的代码散布到用于处理输入的代码中.
对此有什么"更好的方法"?
在C中有各种读取输入的标准方法.在输入缓冲区中还有一些特定于平台的忽略文本的方法,但是如果你fgets
用来读取一行输入而不是scanf
读取一些输入,则不需要这样做.输入的最后一行.
fgets
(读取输入直到'\n'或文件末尾)后跟sscanf
(解析一个字符串输入)是安全的缓冲区溢出,并将吸收任何额外的输入和行终止'\n':
#includeint main ( void ) { int input; char buf[16] = ""; fgets ( buf, sizeof buf, stdin ); sscanf ( buf, "%d", &input ); printf ( "The input is %d.\n", input ); fflush ( stdout ); getchar(); return 0; }
stdout
在printf
终端IO通常不需要刷新之后,但是如果你将它连接到磁盘上(通常在你记录崩溃程序时它会在崩溃之前失去最有趣的一点,如果你不同花顺).
因为fgets
读取并包括行的末尾,所以缓冲区中没有剩余字符,因此您只需要一个getchar
,并且稍微笨拙的输入,例如1234
SpaceEnter不会导致程序终止而不会暂停.
但是,大多数情况下,您不需要在运行控制台应用程序后等待 - 在Linux或其他Unix系统上,您通常打开一个控制台并在那里运行程序,然后控制权返回到shell.在Windows上,诸如Visual Studio之类的IDE通常运行程序并使用以下内容暂停它:
"C:\WINDOWS\system32\cmd.exe" /c ""...\ConsoleApplication1.exe" & pause"
或者您可以打开cmd.exe并从那里运行它,或者您可以使用.pif快捷方式运行它并将其设置为不在退出时关闭控制台,或者您可以创建运行它并暂停的批处理文件.
如果你在Windows上并且你正在使用调试器来运行它并且你没有设置任何断点,那么你真的只需要让程序暂停.