我知道有atox
,strtox
和stox
个系列,但我似乎无法在标准库中找到任何基于迭代器的字符串到int转换或者提升。
我需要它们的原因是因为我有一个解析器,其匹配结果是引用输入字符串的范围。我可能有一个像
这样的输入字符串...8973893488349798923475...
^begin ^end
所以我需要738934883
作为整数。
当然,我可以先begin
和end
构建std::string
以便与上述任何一个家庭一起使用,但我非常希望避免这种开销。
所以我的问题:标准库或Boost中是否有任何东西接受迭代器作为输入,或者我是否必须自己编写。
答案 0 :(得分:2)
Boost确实支持使用Lexical Cast库。以下代码使用子字符串范围来解析数字而不执行任何动态分配:
#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;
}
输出(在OS X上使用Boost 1.60进行测试):
738934883
词汇演员库有一些很好的功能,可以转换为字符串,也可以从字符串转换,但由于某些原因,它并不像其他一些人那样众所周知。
答案 1 :(得分:0)
直到gavinb的回答,我才知道任何这样的库函数。我的尝试就是这样,使用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;
如果你只有const_iterators可用,则必须在修改之前将const_cast应用于* e。
请注意,此解决方案不是线程安全的。
答案 2 :(得分:0)
你可以用strstream来做,但它被剥夺了。以下两个示例,使用strstream和boost数组:
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;
}
答案 3 :(得分:0)
使用现代STL实现std::string(begin,end)
并不是那么糟糕 - SSO消除了对字符串的任何分配,小于~15个字符(22位为64位)。