假设我们有一个字符范围:
// For example
const char *valueBegin="123blahblah"; // Beginning of value
const char *valueEnd=valueBegin+3; // One past end of value
...,我想将其转换为int:
int value=...// Given valueBegin and valueEnd, calculate
// the number stored starting at valueBegin
有什么好的C ++ 11方法可以做到这一点?
显然,您可以创建std::string
并使用stoi
,或将其复制到临时的NUL终止字符数组,然后很容易(例如,通过atoi
或{{1} })。
考虑一种不涉及将字符复制到某个临时数组/对象的方法 - 换句话说,就是一个适用于字符数据的函数。
更新:
很多答案,但在回答之前请先思考。范围未strtol
终止,因此需要NUL
。你不知道超出值的是什么(也就是说,valueEnd可能超出了包含该值的缓冲区),所以如果你的答案没有使用valueEnd
,那就错了。此外,如果您的答案创建了临时valueEnd
对象,则不在此问题的指导范围内。
答案 0 :(得分:6)
std::cout << boost::lexical_cast<int>(sBegin, 3) << std::endl;
这不会产生任何临时性并支持任何类型的角色范围。它也很fast。
如果您想避免使用长度说明符,则可以使用boost::iterator_range
:
std::cout << boost::lexical_cast<int>(boost::make_iterator_range(begin, end)) << std::endl;
答案 1 :(得分:1)
没有任何错误检查,这看起来很简单。
int number = 0;
for ( char* cp = valueBegin; cp != valueEnd; ++cp )
{
number += number*10 + (cp-'0');
}
如果您需要在第一个非数字位置停止,
int number = 0;
for ( char* cp = valueBegin; cp != valueEnd && isdigit(*cp); ++cp )
{
number += number*10 + (cp-'0');
}
如果您需要能够提取负数并能够优雅地处理前导+/-
符号,则代码将变得更复杂。
int number = 0;
char* cp = valueBegin;
int sign = 1;
if ( *cp == '-' )
{
sign = -1;
++cp;
}
if ( *cp == '+' )
{
++cp;
}
for ( ; cp != valueEnd && isdigit(*cp); ++cp )
{
number += number*10 + (cp-'0');
}
number *= sign;
答案 2 :(得分:0)
如果您不想使用Boost并且不介意需要将数字复制到临时字符串,则可以使用std::stoi
执行此操作:
std::cout << std::stoi(std::string(valueBegin, valueEnd)) << std::endl;
还有针对不同数字类型的其他转换器 - stol
,stoul
,stoll
,stoull
,stof
,{{1 },stod
。
这些是在C ++ 11中定义的。
(就个人而言,我会采用Boost选项,但是有些人可能不想要额外的依赖。)