在C ++中从字符串中检索unsigned long的最安全和最好的方法是什么?
我知道一些可能的方法。
首先,转换从atol获取的签名长。
char *myStr; // Initalized to some value somehow.
unsigned long n = ((unsigned)atol(myStr));
这个问题的一个明显问题是,当myStr中存储的值大于signed long可以包含的值时会发生什么? atol检索了什么?
下一种可能性是使用strtoul。
char *myStr; // Initalized to some value somehow.
unsigned long n = strtoul(myStr, 0, 10);
然而,这对我的需求来说有点复杂。我想要一个简单的函数,字符串输入,unsigned long base 10 out。此外,错误处理还有很多不足之处。
我发现的最后一种可能性是使用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库中的任何东西都会将字符串干净地转换为unsigned long并在失败时抛出异常?
如果这是一个骗局我道歉,但我找不到任何与我完全匹配的问题。
答案 0 :(得分:5)
一种方法:
stringstream(str) >> ulongVariable;
答案 1 :(得分:5)
你可以毫无问题地使用strtoul。该函数返回unsigned long。如果无法执行转换,则函数返回0.如果正确的long值超出范围,则函数返回ULONG_MAX,并将errno全局变量设置为ERANGE。
答案 2 :(得分: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);
答案 3 :(得分:2)
如果您可以使用boost库(www.boost.org)查看转换库 - 它只是一个标题包含
#include "boost/lexical_cast.hpp"
然后您需要做的就是
unsigned long ul = boost::lexical_cast<unsigned long>(str);
答案 4 :(得分:1)
Jeffrey Stedfast has a beautiful post关于为Mono编写int解析器例程(在C中) 它生成的代码使用本机类型(您需要32位来解析32位)和错误代码才能溢出。
答案 5 :(得分:1)
使用“atol”内置的std函数
例如std :: string input =“1024”;
的std ::蒂(input.c_str());
Atol期望参数为c字符串类型,因此c_str()会为您执行此操作。
答案 6 :(得分:0)
健壮的方式将是 写一个静态函数并使用它
bool str2Ulong(const string& str,unsigned long & arValue)
{
char *tempptr=NULL;
arValue=strtoul(str,tempptr,10);
return ! (arValue==0 && tempptr==str.c_str());
}