[英]Converting a character range to int
Suppose we have a character range: 假设我们有一个字符范围:
// For example
const char *valueBegin="123blahblah"; // Beginning of value
const char *valueEnd=valueBegin+3; // One past end of value
..., and I want to convert it to an int: ...,我想将其转换为int:
int value=...// Given valueBegin and valueEnd, calculate
// the number stored starting at valueBegin
What are some good C++11 ways to do that? 有什么好的C ++ 11方法可以做到这一点?
Obviously you can create an std::string
and use stoi
, or copy it to a temporary NUL-terminated character array and then it's easy (eg, via atoi
or strtol
). 显然,您可以创建一个
std::string
并使用stoi
,或将其复制到以NUL终止的临时字符数组中,然后就很容易了(例如,通过atoi
或strtol
)。
Think about a way that doesn't involve copying the characters to some temporary array/object - in other words a function that works on the character data in-place. 考虑一种不涉及将字符复制到某个临时数组/对象的方法,换句话说,就是就地处理字符数据的函数。
Update : 更新 :
Lots of answers, but please think before you answer. 答案很多,但请先思考再回答。 The range is not
NUL
terminated, hence the need for valueEnd
. 该范围不是
NUL
终止的,因此需要valueEnd
。 You don't know what is beyond the value (ie, perhaps valueEnd is beyond the buffer containing the value), so if your answer does not use valueEnd
, it is wrong. 您不知道值之外的内容(即,也许valueEnd超出了包含值的缓冲区),因此,如果您的答案不使用
valueEnd
,那就错了。 Also, if your answer creates a temporary std::string
object, it is not within the guidelines of this question. 另外,如果您的答案创建了一个临时的
std::string
对象,则不在此问题的指导范围之内。
Use boost::lexical_cast
: 使用
boost::lexical_cast
:
std::cout << boost::lexical_cast<int>(sBegin, 3) << std::endl;
This does not create any temporaries and supports any kind of character range. 这不会创建任何临时文件,也不支持任何类型的字符范围。 It's also quite fast .
它也相当快 。
If you want to avoid the length specifier then you can use boost::iterator_range
: 如果要避免使用长度说明符,则可以使用
boost::iterator_range
:
std::cout << boost::lexical_cast<int>(boost::make_iterator_range(begin, end)) << std::endl;
Without any error checks, this seems simple enough. 没有任何错误检查,这似乎很简单。
int number = 0;
for ( char* cp = valueBegin; cp != valueEnd; ++cp )
{
number += number*10 + (cp-'0');
}
If you need to want to stop at the first non-digit, 如果您需要停在第一个非数字位数,
int number = 0;
for ( char* cp = valueBegin; cp != valueEnd && isdigit(*cp); ++cp )
{
number += number*10 + (cp-'0');
}
If you need to be able extract negative numbers and be able to gracefully deal with leading +/-
signs, the code will become a little bit more complex. 如果您需要能够提取负数并能够正常处理前导
+/-
号,则代码将变得更加复杂。
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;
If you don't want to use Boost and don't mind needing to copy the digits to a temporary string, you can do this with std::stoi
: 如果您不想使用Boost并且不介意需要将数字复制到临时字符串,则可以使用
std::stoi
进行此std::stoi
:
std::cout << std::stoi(std::string(valueBegin, valueEnd)) << std::endl;
There's other converters for different numeric types as well - stol
, stoul
, stoll
, stoull
, stof
, stod
, stold
. 还有其他用于不同数字类型的转换器
stol
, stoul
, stoll
, stoull
, stof
, stod
, stold
。
These are defined in C++11. 这些在C ++ 11中定义。
(Personally, I would take the Boost option, but some people might not want the additional dependency.) (就我个人而言,我会选择Boost选项,但有些人可能不想要其他依赖项。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.