Ошибка разделения строки в C ++ (сложный способ)

0

Я пытаюсь выплюнуть строку в 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'

  • 0
    отлаживать код?
  • 0
    Я старался изо всех сил , но я не могу заставить его работать ... У меня есть cout в моем коде; там первый символ на typename C::value_type(beg, it) , но я не могу положить это в output
Показать ещё 2 комментария
Теги:
string
visual-c++
split
boost

2 ответа

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; }

Отказ от ответственности: код не тронут руками компилятора.

  • 0
    О боже, я никогда не буду думать об этом сам, большое спасибо !!!
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 "));

Или используйте любой разделитель (ы), который вы хотите использовать в качестве третьего аргумента.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню