我正在尝试将输入解析为 unsigned short。输入可以是任何东西,但我们只能接受十六进制或十进制。它需要适合 unsigned short 因此没有负值或超过 0xffff (65535)。无效值必须使用 C++ 功能适本地报告错误并提供足够的信息。
我的尝试(但它不检查无效的十六进制值,例如 5xffff):
void parse_input(char *input, unsigned short &output)
{
std::string soutput(input);
int myint1;
try
{
myint1 = std::stoi(soutput, 0, 0);
if (myint1 > std::numeric_limits<unsigned short>::max())
{
std::cerr << "Value: " << myint1
<< " is out of bounds!" << std::endl;
exit(EXIT_FAILURE);
}
output = myint1;
}
catch (std::exception &e)
{
std::cerr << "exception caught: " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
}
另一种尝试也没有做到所有这些(显然使用 errno 是 Not Acceptable ):
auto n = strtoul(argv[2], NULL, 0);
if (errno == ERANGE || n > std::numeric_limits<unsigned short>::max()) {
}
else {
}
因此,基于上述内容的实际问题是,使用 C++ 功能解决此问题的最有效方法是什么?请举例说明。
非常感谢。
最佳答案
So the actual question based on the above is, what is the most efficient and effective way to resolve this using C++ features? Please provide an example.
由于您的输入数字似乎使用 0x
来区分十六进制输入并且没有前缀用于十进制数字,因此这是一个使用自定义 I/O 操纵器的小解决方案:
std::istream& hex_or_decimal(std::istream& is) {
char peek = is.peek();
int zero_count = 0;
while(peek == '0' || std::isspace(peek)) {
if(peek == '0') {
++zero_count;
}
// Consume 0 prefixes as they wont affect the result
char dummy;
is.get(dummy);
peek = is.peek();
if((peek == 'x' || zero_count) && zero_count <= 1) {
is.get(dummy);
is >> std::hex;
return is;
}
}
is >> std::dec;
return is;
}
然后像这样使用:
int main()
{
std::istringstream iss { "5 0x42 33 044 00x777 0x55" };
short input = 0;
while(iss >> hex_or_decimal >> input) {
std::cout << std::dec << input
<< " 0x" << std::hex << input << std::endl;
}
if(iss.fail()) {
std::cerr << "Invalid input!" << std::endl;
}
}
输出是
5 0x5
66 0x42
33 0x21
44 0x2c
Invalid input!
查看实例 here请。
注意:
5xfffff
值在 5
被流正确使用后被标记为无效(参见演示 here )
您可以使用 std::istream
标准功能和标志轻松地使其适应您的需求(例如,在无效输入时抛出异常)。
例如:
抛出和捕获异常
int main()
{
std::istringstream iss { "5 0x42 33 044 00x777 0x55" };
iss.exceptions(std::ifstream::failbit); // <<<
try {
short input = 0;
while(iss >> hex_or_decimal >> input) {
std::cout << std::dec << input
<< " 0x" << std::hex << input << std::endl;
}
}
catch (const std::ios_base::failure &fail) { <<<
std::cerr << "Invalid input!" << std::endl;
}
}
关于c++ - Char* 输入检查它是十六进制还是十进制,并使用适当的错误处理和报告将其解析为无符号短整型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45533444/