我有一个具有命令行功能的Qt gui应用程序。为此,我将其添加到main()
函数的顶部:
#ifdef _WIN32
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
freopen("CONOUT$", "w", stdout);
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stderr);
}
#endif
然后构造了我的主类的实例。在构造函数中,QCommandLineParser
确定是否有任何参数,并创建cmdline解析类或gui应用程序类的实例。
在cmdline解析类中,我要求用户输入某些值:
QString qanswer;
// `answerToInt` is an std::unordered_map
while (answerToInt.find(qanswer) == answerToInt.end()) {
std::cout << std::endl << "File will be overwritten:" << std::endl
<< path.toStdString() << std::endl
<< "Are you sure? " << (multiple ? "(Yes/YesAll/No/NoAll)" : "(Yes/No)") << std::endl;
std::string answer;
std::cin >> answer;
qanswer = QString::fromStdString(answer).toLower();
std::cin.clear();
}
当输入“是”,“否”,“是全部”或“否全部”(不区分大小写)时,程序将按预期继续,但是当用户输入其他内容时,cmd会抛出此错误:
'[input]'不被识别为内部或外部命令[...]
然后再次显示“ C:\ path \ to \ exe>”,用户可以继续输入直到键入正确的值之一为止。输入有效的字符串后,它将按预期再次继续。
我尝试过this answer和std::getline()
,但没有区别。
所以如何防止错误出现并继续显示cout
?
AttachConsole
只是附加到父进程的控制台,它不会阻止父进程也从中读取信息。因此,控制台输入被插入到父进程(cmd.exe
)和您的应用之间,这在管理上可能会遇到问题(有人建议killing父进程,这显然不是一个好主意)。
您可以做的是始终创建new控制台(请参阅AllocConsole
)。
或者如果您想重新使用same控制台,则可以改而以Console子系统为目标(链接器选项AllocConsole
),并使用常规的/SUBSYSTEM:CONSOLE
功能代替main()
(是的,您可以在WinMain
中创建Win32 Windows 和处理控制台I / O。
您甚至可以拥有一个多子系统源代码,该源代码可以像这样用垫片作为Windows和Console子系统进行链接(main()
和命令行参数有待实现):
nCmdShow