在C++程序中暂停控制台的最佳方法是什么?
- 使用
cin.get()
- 或者使用
system("pause")
- 还是使用像
getch()
或getchar()
这样的C函数?
使用system("pause")
是否会导致非可移植代码并且不能在UNIX上工作?
cin.get()
是否更好用于暂停控制台?
在C++程序中暂停控制台的最佳方法是什么?
cin.get()
system("pause")
getch()
或getchar()
这样的C函数?使用system("pause")
是否会导致非可移植代码并且不能在UNIX上工作?
cin.get()
是否更好用于暂停控制台?
可能有一种最佳方式(比如使用可移植的 cin.get()
),但是并没有一个好的方式存在。完成任务的程序应该退出并将其资源归还给计算机。
是的,任何使用system()
都会导致不可移植的代码,因为参数传递给拥有您进程的shell。
在您的源代码中有暂停代码,早晚会引起麻烦:
#define
太可怕了相反,探索您的IDE。它可能有一个选项,在运行后不关闭控制台窗口。如果没有,作为一位值得花钱的开发人员,总是在附近打开控制台窗口绝对是一个很好的理由。
或者,您可以将其作为程序选项,但我个人从未见过一个带有 --keep-alive-when-dead
选项的程序。
故事的寓意:这是用户的问题,而不是程序的问题。不要污染你的代码。
如果您想编写可移植的C++代码,我建议使用cin.get()
。
system("PAUSE")
在Windows上有效,因为它需要执行名为"PAUSE
"的控制台命令。但是我不确定其他操作系统如Linux或其他Unix衍生版本是否支持它。因此,这往往是不可移植的。
由于C++已经提供了cin.get()
,我认为没有必要使用C的getch()
。
getch()
,因为它没有在ISO C++或POSIX中定义(它来自于MS conio.h
)。 - Grzegorz Szpetkowski最佳方式很大程度上取决于目标平台、调试与发布用途等方面。
我认为没有一种最好的方式,但是在相当通用的情况下“强制”等待输入场景,特别是在调试时(通常会根据 NDEBUG
或 _DEBUG
进行编译或禁用),您可以尝试以下的 std::getline
:
inline void wait_on_enter()
{
std::string dummy;
std::cout << "Enter to continue..." << std::endl;
std::getline(std::cin, dummy);
}
system("pause");
和 getch();
(来自DOS世界,如果我没记错)都不可移植。没有一种“好”的方法来做到这一点,但您应该使用可移植的解决方案,因此避免在您的情况下使用system()
调用,您可以使用cin.get()
或getch()
,就像您在问题中提到的那样,还有一个建议。使所有暂停都由一个(或很少几个)预处理器定义控制。
例如:
在全局文件中:
#define USE_PAUSES
#ifndef _DEBUG //I asume you have _DEBUG definition for debug and don't have it for release build
#undef USE_PAUSES
#endif
在代码的某个地方
#ifdef USE_PAUSES
cin.get();
#endif
这不是通用的建议,但是在发布版本中应保护自己免受放置暂停的影响,并且这些应该易于控制,我提到的全局文件可能并不是那么全局,因为对其进行更改可能导致编译时间非常长。
system("pause")
是在Windows控制台暂停的一种有效方式,"pause"实际上是Windows识别的系统命令,因此您不必担心它调用同名程序或类似的问题。关于system("pause")
有危险性的观点是错误的。
然而在Windows以外的平台上情况并非如此,因此最好使用预处理器来区分平台。
#ifdef _WIN32 || _WIN64
if(argc <= 1) // optional, prevents pausing if the user runs "program.exe -lol"
system("pause");
#endif
我的答案部分基于Yoank的回答,部分基于另一个问题上Justin Time的评论。
cout << endl << "Press <Enter> to continue...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin.get();
我经常使用几行代码来清除输入流中的任何字符,然后等待输入以忽略它们。
类似这样:
void pause() {
cin.clear();
cout << endl << "Press any key to continue...";
cin.ignore();
}
虽然回复晚了,但我认为这会对其他人有帮助。
模拟 system("pause") 的一部分是模拟它要求用户执行的操作:“按任意键继续...” 所以,我们需要一些东西,它不仅等待简单的回车键,就像 std::cin.get() 所做的那样。即使使用 getch() 两次也会遇到问题(如果在同一按键后立即再次暂停,则已经注意到第二个调用通常会跳过暂停)。我认为这与输入缓冲有关系。通常不建议使用 system("pause"),但我们仍然需要模拟用户可能已经期望的操作。我更喜欢 getch(),因为它不会在屏幕上显示,而且可以动态工作。
解决方案是使用 do-while 循环执行以下操作:
void Console::pause()
{
int ch = 0;
std::cout << "\nPress any key to continue . . . ";
do {
ch = getch();
} while (ch != 0);
std::cout << std::endl;
}
这对我有效。
void pause()
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
std::string dummy;
std::cout << "Press any key to continue . . .";
std::getline(std::cin, dummy);
}