简体   繁体   English

将字符范围转换为int

[英]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终止的临时字符数组中,然后就很容易了(例如,通过atoistrtol )。

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 . 还有其他用于不同数字类型的转换器stolstoulstollstoullstofstodstold

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM