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



我在互联网上浏览了一段时间,发现将用户输入作为十六进制数的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:",而不是让用户重试。

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

编辑:

根据建议,我已经看了这篇文章,并相应地调整了我的代码:

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

现在的问题是,如果我输入一个字符串,比如le,它会再次打印提示,但它会继续到代码的其余部分。为什么会这样?如果我去掉cin.ignore(),它会做上面描述的怪事。

cin.ignore()将忽略其内部缓冲区中的最后一个字符。您需要使用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 numbern"; 
}
}

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

最新更新