7

从 C++ 中的字符串中检索无符号长整数的最安全和最好的方法是什么?

我知道许多可能的方法。

首先,转换取自 atol 的有符号长整数。

char *myStr; // Initalized to some value somehow.
unsigned long n = ((unsigned)atol(myStr));

一个明显的问题是,当存储在 myStr 中的值大于有符号的 long 可以包含的值时会发生什么?atol 检索什么?

下一种可能性是使用 strtoul。

char *myStr; // Initalized to some value somehow.
unsigned long n = strtoul(myStr, 0, 10);

但是,这对于我的需求来说有点过于复杂。我想要一个简单的函数,字符串输入,无符号长基数 10 输出。此外,错误处理还有很多不足之处。

我发现的最后一种可能性是使用 sscanf。

char *myStr; // Initalized to some value somehow.
unsigned long n = 0;
if(sscanf(myStr, "%lu", n) != 1) {
    //do some error handling
}

同样,错误处理还有很多不足之处,而且比我想要的要复杂一些。

剩下的显而易见的选择是编写我自己的包装器,或者围绕先前的可能性之一,或者在字符串中循环并手动转换每个数字直到达到 ULONG_MAX 的东西。

我的问题是,我的 google-fu 找不到的其他选项是什么?C++ std 库中的任何东西都可以将字符串干净地转换为无符号长整数并在失败时抛出异常?

如果这是一个骗局,我深表歉意,但我找不到任何与我完全匹配的问题。

4

7 回答 7

6

您可以毫无问题地使用 strtoul。该函数返回一个无符号长整数。如果无法执行转换,则函数返回 0。如果正确的 long 值超出范围,则函数返回 ULONG_MAX 并且 errno 全局变量设置为 ERANGE。

于 2009-09-27T18:47:33.830 回答
5

一种方法:

stringstream(str) >> ulongVariable;
于 2009-09-27T18:41:12.103 回答
4
template <class T>
T strToNum(const std::string &inputString,
           std::ios_base &(*f)(std::ios_base&) = std::dec)
{
    T t;
    std::istringstream stringStream(inputString);

    if ((stringStream >> f >> t).fail())
    {
        throw runtime_error("Invalid conversion");
    }
    return t;
}


// Example usage
unsigned long ulongValue = strToNum<unsigned long>(strValue);
int intValue             = strToNum<int>(strValue);

int intValueFromHex      = strToNum<int>(strHexValue,std::hex);
unsigned long ulOctValue = strToNum<unsigned long>(strOctVal, std::oct);
于 2009-09-27T18:47:34.430 回答
2

如果您可以使用 boost 库 (www.boost.org),请查看转换库 - 它只是一个标头包含

#include "boost/lexical_cast.hpp"

那么你需要做的就是

unsigned long ul = boost::lexical_cast<unsigned long>(str);
于 2009-09-27T18:55:27.940 回答
1

Jeffrey Stedfast 有一篇关于为 Mono(用 C 语言)编写 int 解析器例程的漂亮帖子。
它生成使用本机类型的代码(您需要 32 位来解析 32 位)和溢出的错误代码。

于 2009-09-27T18:49:46.890 回答
1

使用“atol”内置标准函数

例如 std::string 输入 = "1024";

std::atol(input.c_str());

Atol 期望参数是 c 字符串类型,因此 c_str() 会为您执行此操作。

于 2017-11-16T17:42:46.287 回答
0

稳健的方法是编写一个静态函数并使用它

bool str2Ulong(const string& str,unsigned long & arValue)
{
   char *tempptr=NULL;
   arValue=strtoul(str,tempptr,10);

   return ! (arValue==0 && tempptr==str.c_str());

}
于 2009-09-28T06:03:14.583 回答