[英](String)Iterator based conversion to int
There are the atox
, strtox
and stox
families that I know of, but I can't seem to find any iterator based string to int conversions in the Standard Library or Boost.我知道
atox
、 strtox
和stox
系列,但我似乎无法在标准库或 Boost 中找到任何基于迭代器的字符串到 int 转换。
The reason I need them is because I am having a parser whose match result is a range referencing the input string.我需要它们的原因是因为我有一个解析器,它的匹配结果是一个引用输入字符串的范围。 I might very well have an input string like
我很可能有一个输入字符串
...8973893488349798923475...
^begin ^end
so I need 738934883
as an integer.所以我需要
738934883
作为整数。
Of couse, I could first take begin
and end
to construct an std::string
to use with any of above families, but I would very much like to avoid that overhead.当然,我可以先使用
begin
和end
来构造一个std::string
以用于上述任何系列,但我非常想避免这种开销。
So my question: Is there anything in the Standard Library or Boost accepting iterators as input, or do I have to write my own.所以我的问题是:标准库或 Boost 中是否有任何东西接受迭代器作为输入,还是我必须自己编写。
Boost does actually support this, using the Lexical Cast library. Boost 确实支持这一点,使用Lexical Cast库。 The following code uses a substring range to parse the number without performing any dynamic allocation:
以下代码使用子字符串范围来解析数字而不执行任何动态分配:
#include <boost/lexical_cast.hpp>
#include <string>
#include <iostream>
int convert_strings_part(const std::string& s, std::size_t pos, std::size_t n)
{
return boost::lexical_cast<int>(s.data() + pos, n);
}
int main(int argc, char* argv[])
{
std::string s = "8973893488349798923475";
// Expect: 738934883
std::cout << convert_strings_part(s, 2, 9) << std::endl;
return 0;
}
The output (tested on OS X with Boost 1.60):输出(在带有 Boost 1.60 的 OS X 上测试):
738934883
The lexical cast library has some great features for conversion to and from strings, though it isn't as well known as some of the others for some reason.词法转换库有一些很好的转换字符串和从字符串转换的特性,尽管由于某些原因它不像其他一些那样广为人知。
Until gavinb's answer, I was not aware of any such library function.在 gavinb 回答之前,我不知道有任何这样的库函数。 My try would have been this, using any of atox and strtox as follows (you could avoid a dependency on boost library then, if wanted):
我的尝试是这样的,使用 atox 和 strtox 中的任何一个,如下所示(如果需要,您可以避免对 boost 库的依赖):
::std::string::iterator b; // begin of section
::std::string::iterator e; // end of section, pointing at first char NOT to be evaluated
char tmp = *e;
*e = 0;
int n = atoi(&*b);
*e = tmp;
If you only had const_iterators available, you would have to apply a const_cast to *e before modifying.如果您只有 const_iterators 可用,则必须在修改之前将 const_cast 应用于 *e。
Be aware that this solution is not thread safe, though.但是请注意,此解决方案不是线程安全的。
You could do it with strstream but it was depracated.你可以用 strstream 做到这一点,但它已被弃用。 Below two examples, with strstream and boost arrays:
下面是两个带有 strstream 和 boost 数组的示例:
http://coliru.stacked-crooked.com/a/04d4bde6973a1972 http://coliru.stacked-crooked.com/a/04d4bde6973a1972
#include <iostream>
#include <strstream>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/copy.hpp>
int main()
{
std::string in = "8973893488349798923475";
// ^^^^^
auto beg = in.begin()+2;
auto end = in.begin()+6;
// strstream example - DEPRECATED
std::istrstream os(&*beg, end-beg);
int n;
std::string ss;
os >> n;
std::cout << n << "\n";
// Boost example
namespace io = boost::iostreams;
int n2;
io::array_source src(&*beg, end-beg);
io::stream<io::array_source> os2(src);
os2 >> n2;
std::cout << n2 << "\n";
return 0;
}
使用现代 STL 实现std::string(begin,end)
并没有那么糟糕 - SSO 消除了对小于 ~15 个字符(64 位为 22 个)的字符串的任何分配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.