我正在编写程序的一部分,它解析和验证程序控制台参数中的一些用户输入。为此,我选择使用 stringstream,但在读取无符号类型时遇到了问题。
下一个模板用于从给定字符串中读取请求的类型:
#include <iostream>
#include <sstream>
#include <string>
using std::string;
using std::stringstream;
using std::cout;
using std::endl;
template<typename ValueType>
ValueType read_value(string s)
{
stringstream ss(s);
ValueType res;
ss >> res;
if (ss.fail() or not ss.eof())
throw string("Bad argument: ") + s;
return res;
}
// +template specializations for strings, etc.
int main(void)
{
cout << read_value<unsigned int>("-10") << endl;
}
如果类型是无符号的并且输入字符串包含负数,我希望看到异常抛出(由 引起ss.fail() = true
)。但是 stringstream 产生转换为无符号类型值(书面样本中的 4294967286)。
如何修复此示例以实现所需的行为(最好不要回退到 c 函数)?我知道它可以通过简单的第一个符号检查来完成,但我可以放置前导空格。我可以编写自己的解析器,但不相信问题是如此不可预测,标准库无法解决它。
隐藏在无符号类型的字符串流运算符深处的函数是 strtoull 和 strtoul。它们以描述的方式工作,但提到的功能是低级的。为什么 stringstream 不提供一些验证级别?(我只是希望我错了,它确实如此,但需要一些动作来启用它)。