如何从字符串中提取无符号长字符串? 从C++中的字符串中检索无符号长的最安全和最好的方法是什么?< /P>

如何从字符串中提取无符号长字符串? 从C++中的字符串中检索无符号长的最安全和最好的方法是什么?< /P>,c++,long-integer,unsigned,string-parsing,string-conversion,C++,Long Integer,Unsigned,String Parsing,String Conversion,我知道一些可能的方法 首先,转换从atol获取的带符号的long char *myStr; // Initalized to some value somehow. unsigned long n = ((unsigned)atol(myStr)); 明显的问题是,当myStr中存储的值大于有符号long可以包含的值时会发生什么?环礁回收什么 下一种可能性是使用strtoul char *myStr; // Initalized to some value somehow. unsigned

我知道一些可能的方法

首先,转换从atol获取的带符号的long

char *myStr; // Initalized to some value somehow.
unsigned long n = ((unsigned)atol(myStr));
明显的问题是,当myStr中存储的值大于有符号long可以包含的值时会发生什么?环礁回收什么

下一种可能性是使用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库中的任何东西都能将字符串转换为无符号长,并在失败时抛出异常?

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

一种方法:

stringstream(str) >> ulongVariable;

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

模板
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);
T strToNum(const std::string和inputString, std::ios_base&(*f)(std::ios_base&)=std::dec) { T; std::istringstream stringStream(inputString); 如果((stringStream>>f>>t).fail()) { 抛出运行时_错误(“无效转换”); } 返回t; } //示例用法 无符号长ulongValue=strToNum(strValue); intValue=strToNum(strValue); int intValueFromHex=strToNum(strHexValue,std::hex); 无符号长ulOctValue=strotnum(strOctVal,std::oct);
关于为Mono编写int解析器例程(在C中)。

它生成的代码使用本机类型(您需要32位来解析32位)和溢出错误代码。

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

#include "boost/lexical_cast.hpp"
那么你需要做的就是

unsigned long ul = boost::lexical_cast<unsigned long>(str);
无符号长ul=boost::词法转换(str);
稳健的方式将是 编写一个静态函数并使用它

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

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

}
使用“atol”内置std功能

例如std::string input=“1024”

std::atol(input.c_str())


Atol希望参数的类型为c字符串,所以c_str()会为您这样做

atol
:“如果正确的值超出了可表示值的范围,则返回LONG_MAX或LONG_MIN。”有几个问题,我不确定它们是否重复:(1)(2)我不明白你对strtoul有什么不满。这是一个完美的功能。将0传递给base,它将使用您的C库能够理解的任何基前缀字符串(如“0x”)转换数字。我编辑了这个问题,以便更清楚地说明我在使用C样式的字符串。所以这必须是streamstream(string(myStr))>>ulongvariable。这对我来说是一种浪费和低效:/I我宁愿它是更干净、更直接的东西。实际上,这是不必要的,因为
std::string
有一个隐式构造函数,它将C样式的字符串作为参数。该构造函数允许您只编写
stringstream(“无论什么”)
。当然,这是自拍。即便如此,它还是实例化了两个类——以及其中固有的所有内存管理——来完成一个具有单个内部循环的简单函数应该能够完成的任务。我希望在标准库中有类似的东西。好的C++编译器是积极的优化器。永远记住这一点。我不是说这是最快的方式,但它应该是相当快的。@Alcon,在你不得不这样做之前不要考虑性能。您确定此代码需要非常快吗?您确定此解决方案的速度不是非常快吗?如果可能,请查找异常样式的错误处理而不是errno样式。异常样式的错误处理,但不存在类开销?听起来有点自相矛盾:)嗯,函数可以做异常类型的错误处理。我只是不想实例化两个我不需要的类,每次我想转换一个长的。看起来很浪费!我将研究boost库,我曾考虑使用python解释库,因此使用boost可能适合我的需要。不过,如果有一个简单的clean函数,对于那些不想依赖boost库的人来说,那就太好了