使用istream(std cin):防止在Windows上将“ [输入]识别为…”

问题描述 投票:0回答:1

我有一个具有命令行功能的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 answerstd::getline(),但没有区别。

所以如何防止错误出现并继续显示cout

c++ cmd cin
1个回答
0
投票

AttachConsole只是附加到父进程的控制台,它不会阻止父进程也从中读取信息。因此,控制台输入被插入到父进程(cmd.exe)和您的应用之间,这在管理上可能会遇到问题(有人建议killing父进程,这显然不是一个好主意)。

您可以做的是始终创建new控制台(请参阅AllocConsole)。

或者如果您想重新使用same控制台,则可以改而以Console子系统为目标(链接器选项AllocConsole),并使用常规的/SUBSYSTEM:CONSOLE功能代替main()(是的,您可以在WinMain中创建Win32 Windows 处理控制台I / O。

您甚至可以拥有一个多子系统源代码,该源代码可以像这样用垫片作为Windows和Console子系统进行链接(main()和命令行参数有待实现):

nCmdShow
© www.soinside.com 2019 - 2024. All rights reserved.