C ++字符串拆分错误(复杂方式)

时间:2013-12-07 22:46:29

标签: c++ string visual-c++ boost split

我试图用以下方式在C ++中吐出一个字符串:

#include <bitset>
#include <iostream>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/timer.hpp>

using namespace std;
size_t const N = 10000000;

typedef string::const_iterator iter;
typedef boost::iterator_range<iter> string_view;

template<typename C>
void test_custom(string const& s, char const* d, C& ret)
{
    C output;

    bitset<255> delims;
    while (*d)
    {
        unsigned char code = *d++;
        delims[code] = true;
    }
    typedef string::const_iterator iter;
    iter beg;
    bool in_token = false;

    bool go = false;

    for (string::const_iterator it = s.begin(), end = s.end(); it != end; ++it)
    {
        if (delims[*it])
        {
            if (in_token)
            {

                output.push_back(typename C::value_type(beg, it));
                in_token = false;
            }
        }
        else if (!in_token)
        {
            beg = it;
            in_token = true;
        }
        else
        {
            if (!go)
            {
                cout << typename C::value_type(beg, it);
                //outputs the first character
                go = true;
            }
        }
    }

    if (in_token)
        output.push_back(typename C::value_type(beg, s.end()));
    output.swap(ret);
}

vector<string_view> split_string(string in, const char* delim = " ")
{
    vector<string_view> vsv;
    test_custom(in, delim, vsv);

    return vsv;
}

int split()
{
    string text = "123 456";

    vector<string_view> vsv = split_string(text);

    for (int i = 0; i < vsv.size(); i++)
        cout << endl << vsv.at(i) << "|" << endl;

    return 0;
}

这里的问题是第一个角色因某种原因被删除...返回的字符串是'23'和'456'但是我希望它们是'123 '和'456'

所以,第一个字符是''而不是'1'

2 个答案:

答案 0 :(得分:4)

我不熟悉boost::iterator_range,但它确实听起来像是一对迭代器。

如果是,那么在此代码中:

vector<string_view> split_string(string in, const char* delim = " ")
{
    vector<string_view> vsv;
    test_custom(in, delim, vsv);

    return vsv;
}

您将返回引用名为string的本地in的迭代器,该函数在函数返回时已不复存在。

那是未定义的行为。

一种解决方法是通过引用传递该字符串。


顺便说一句,在空格上拆分字符串的一种低效但简单而安全的方法是使用istringstream

istringstream stream( source_string );
string word;
while( stream >> word ) { cout << word; }

免责声明:编码器未触及代码。

答案 1 :(得分:1)

由于你已经在使用Boost,你可以使用它(“简单”方式:P):

#include <boost/algorithm/string.hpp>

std::string text = "this is sample string";
std::vector<std::string> tokens;
boost::split(tokens, text, boost::is_any_of("\t "));

或者使用您想要用作第三个参数的任何分隔符。