通过错误处理在 C++ 中可靠地获取用户十六进制输入

Reliably get user hex input in C++ with error handling

我在 Internet 上搜索了一段时间,发现 C++ 将用户输入作为十六进制数的方式是使用 cin >> hex >> variable。我目前无法在我的情况下使用它。以下是我希望针对一系列用户输入发生的情况:

>0xFF    -> variable = 0xFF;
>FF      -> variable = 0xFF;
>122     -> variable = 0x122;
>garbage -> ask again;
>0XFfFfA -> variable = 0xFFFFA;

这是我的代码及其问题:

int endAddr;
do { printf("Enter end addr: ");   } while (!(cin >> hex >> endAddr));

问题:输入垃圾后,继续循环打印出来"Enter end addr: ",而不是让用户重试。

有关此代码片段的任何帮助都将非常有用。提前致谢。

编辑:

根据建议,我查看了 this post 并相应地调整了我的代码:

while (true) {
    printf("Enter start addr: ");
    if (cin >> hex >> startAddr) {
        break;
    }
    cin.clear();
    cin.ignore();
}
//rest of code

现在的问题是,如果我输入一个字符串,例如 le,它会再次打印提示,但是它会继续执行其余代码。为什么是这样?如果我删除 cin.ignore(),它会执行上面描述的循环操作。

cin.ignore() 将忽略其内部缓冲区中的 last 字符。您需要使用 cin.ignore(std::numeric_limits<std::streamsize>::max()) 重置回最后一个 EOF。然后你可以可靠地检查下一个输入。

在尝试解决这个问题之后(流的良好实践 :D),我想出了一个解决方案

    int startAddr;
    std::cin.exceptions(std::ios_base::failbit);

    while (true) {
        std::cout << "Enter start addr: ";

        try {
            std::cin >> std::hex >> startAddr;
            break;
        } catch(std::exception&) {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
            std::cout << "Invalid number\n"; 
        }
    }

这利用了将故障位设置为 std::iostreams 异常的能力,这意味着我们可以保证捕获错误,std::numeric_limits 作为清除缓冲区的更可靠方法