使用 istream (std cin):防止 Windows 上的“[输入] 未被识别为...”

2024-04-22

我有一个具有命令行功能的 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();
}

当输入“Yes”、“No”、“YesAll”或“NoAll”(不区分大小写)时,程序按预期继续,但当用户输入除此之外的内容时,cmd 会抛出以下错误:

“[输入]”未被识别为内部或外部命令 [...]

然后再次显示“C:\path\to\exe>”,用户可以继续输入,直到键入正确的值之一。 输入有效字符串后,它会按预期再次继续。

I tried 这个答案 https://stackoverflow.com/a/5864560/1136512std::getline(),但这没有什么区别。

那么如何防止错误出现并继续显示cout?


AttachConsole只是附加到父进程的控制台,它不会阻止父进程也从中读取。因此控制台输入在父进程之间交错(cmd.exe)和你的应用程序,这可能会带来管理问题(有些人建议killing https://stackoverflow.com/questions/5629393/using-attachconsole-while-the-process-ive-attached-with-is-running-and-spewing父进程,这显然不是一个好主意)。

相反,你可以做的是始终创建一个new控制台(参见AllocConsole https://learn.microsoft.com/en-us/windows/console/allocconsole).

或者如果您想重新使用same控制台,以控制台子系统为目标可能是一个想法(链接器选项/SUBSYSTEM:CONSOLE)并有规律的main()函数而不是WinMain(是的,您可以创建 Win32 窗口and处理控制台 I/O 全部在内部main()).

您甚至可以拥有一个可以像 Windows 一样链接的多子系统源以及具有这样的垫片的控制台子系统(nCmdShow并且命令行参数仍有待实现):

HWND hwnd;

int main() {
    std::thread t([] {
        // let GUI run in its own thread ...
        WinMain(GetModuleHandle(NULL), NULL, "", SW_SHOWDEFAULT);
        exit(0);
    });
    // meanwhile in this thread we handle console I/O ...
    std::string s;
    std::cout << "Press Enter to exit" << std::endl;
    while (std::getline(std::cin, s)) {
        if (s == "")
            break;
        std::cout << "Hello " << s << std::endl;
    }
    PostMessageA(hwnd, WM_CLOSE, 0, 0);
    t.join();
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
     // Your normal WinMain.
     // CreateWindow, GetMessage loop etc. . .
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 istream (std cin):防止 Windows 上的“[输入] 未被识别为...” 的相关文章

  • 使用 gcc 在 Linux 上运行线程构建块 (Intel TBB)

    我正在尝试为线程构建块构建一些测试 不幸的是 我无法配置 tbb 库 链接器找不到库 tbb 我尝试在 bin 目录中运行脚本 但这没有帮助 我什至尝试将库文件移动到 usr local lib 但这又失败了 任何的意见都将会有帮助 确定您
  • 删除文件的最后 10 个字符

    我想删除文件的最后 10 个字符 说一个字符串 hello i am a c learner 是文件内的数据 我只是希望该文件是 hello i am a 文件的最后 10 个字符 即字符串 c learner 应在文件内消除 解决方案 将
  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include

随机推荐