通过错误处理在 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::iostream
s 异常的能力,这意味着我们可以保证捕获错误,std::numeric_limits
作为清除缓冲区的更可靠方法
我在 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::iostream
s 异常的能力,这意味着我们可以保证捕获错误,std::numeric_limits
作为清除缓冲区的更可靠方法