【问题标题】:How do I handle overflow / underflow when converting std::string to integer?将 std::string 转换为整数时如何处理溢出/下溢?
【发布时间】:2013-02-19 15:23:41
【问题描述】:

我正在尝试使用 std::istringstream

将数字 std::string 转换为 integer
std::istringstream convertor;

convertor.str(mystring);
convertor >> myint;

如果数字字符串超过(或低于)整数的限制,我想抛出异常,但我不知道最好的方法是什么。我想知道是否有特定于 std::istringstream 的东西或专门为此目的制作的其他东西,还是我必须使用脏(至少看起来脏:))方式与numeric_limits

感谢您的帮助。

【问题讨论】:

标签: c++ types overflow


【解决方案1】:
std::istringstream convertor;
convertor.str(mystring);
if(!(convertor >> myint)) {
    thow std::invalid_argument();
}

应该注意,标准库中已经提供了这样的功能。 (C++11)

it=std::stoi(my_string);

http://en.cppreference.com/w/cpp/string/basic_string/stol

此外,这可以说是异常滥用,作为函数的先决条件是mystring 应该表示一个整数值,如果这不是先决条件,那么它是处理这种情况的函数正常流程控制的一部分不在的地方。

我可能会写:

std::pair<bool, int> try_to_int(const std::string& str);

或者 boost::optional 在这里也可以很好地工作

【讨论】:

  • 只有当你有 C++11(大多数人不是这样)。
  • @JamesKanze “这不是大多数人的情况”谁说的?我链接的文档也提到了这一事实。
  • 我想知道@111111 您(或标准)认为处理无效输入的正确方法是什么?只是做一些未定义的行为?
  • 如果流包含"quack"out_of_range 会抛出一个可疑的东西,这就是为什么stoi 也可以抛出invalid_argument
  • @JonasWielicki 我不认为标准在这个问题上说太多,我个人为无效输入编写断言,因为如果我给一个函数提供无效输入,那就是一个错误。
【解决方案2】:

如果您可以访问 C++11 功能,请尝试std::stoi(my_string);

如果您没有,但可以访问 boost 库,请尝试:

std::string str("112211"); 
int x = 0;
try
{
    x = boost::lexical_cast<int>(str);
}
(catch boost::bad_lexical_cast&)
{
}

boost::lexical cast 被定义(至少对于一般情况),在内部使用istringstream(如果你覆盖std::istream&amp; operator&gt;&gt;your_type,你将能够用lexical_cast&lt;your_type&gt;(string) 读取你的类型);

如果您也无权访问 boost,请自行开发(此线程中的其他人已经指出如何设置 iostream 以引发异常)。

编辑:滚动你自己的:

template<typename T>
T lexical_cast<T>(const std::string & str)
{
    std::istringstream buffer(str);
    buffer.exceptions(std::istringstream::failbit);
    T retval;
    buffer >> retval;
    return retval;
}

对于不支持 iostream io 的值类型,您可以特别说明这一点。

【讨论】:

  • 这个方法我也不能用……我不能用boost库。
【解决方案3】:

感谢您的回答,我在问题的 cmets 中找到了解决方案:

std::istringstream convertor;

convertor.str("16");
convertor >> myint;
if (convertor.fail())
    std::cerr << "error" << std::endl;

或者,抛出异常:

std::istringstream convertor;

convertor.exceptions(std::istringstream::failbit);
convertor.str("16");
convertor >> myint;

【讨论】:

    猜你喜欢
    • 2011-08-12
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    • 1970-01-01
    • 2012-09-19
    相关资源
    最近更新 更多