Разделить строку по указанному разделителю - PullRequest
3 голосов
/ 24 марта 2011

У меня есть переменная std :: wstring, которая содержит текст, и мне нужно разделить его по разделителю.Как я мог это сделать?Я не использовал бы повышение, которое генерирует некоторые предупреждения.Спасибо

РЕДАКТИРОВАТЬ 1 это пример текста:

привет, как дела?

и это код:

typedef boost::tokenizer<boost::char_separator<wchar_t>, std::wstring::const_iterator, std::wstring> Tok;

boost::char_separator<wchar_t> sep;

Tok tok(this->m_inputText, sep);

for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter)
{
    cout << *tok_iter;
}

результаты:

  1. привет
  2. как
  3. вы
  4. ?

Я не понимаю, почему последний символ всегда разделяется на другой токен ...

Ответы [ 4 ]

4 голосов
/ 25 марта 2011

В вашем коде вопросительный знак появляется в отдельной строке, потому что именно так по умолчанию работает boost :: tokenizer.

Если желаемое значение равно четырем токенам («hi», «how», «are»и "вы?"), вы могли бы

а) изменить используемый вами char_separator на

boost::char_separator<wchar_t> sep(L" ", L"");

б) использовать boost::split, что, я думаю, является самым прямым ответом"разбить строку по заданному символу"

#include <string>
#include <iostream>
#include <vector>
#include <boost/algorithm/string.hpp>

int main()
{

        std::wstring m_inputText = L"hi how are you?";

        std::vector<std::wstring> tok;
        split(tok, m_inputText, boost::is_any_of(L" "));

        for(std::vector<std::wstring>::iterator tok_iter = tok.begin();
                        tok_iter != tok.end(); ++tok_iter)
        {
                std::wcout << *tok_iter << '\n';
        }

}

тестовый прогон: https://ideone.com/jOeH9

1 голос
/ 25 марта 2011

Вы строите по умолчанию boost::char_separator. В документации написано:

Функция std :: isspace () используется для идентификации пропущенных разделителей, а std :: ispunct () используется для идентификации сохраненных разделителей. Кроме того, пустые токены удаляются.

Поскольку std::ispunct(L'?') имеет значение true, он рассматривается как «сохраненный» разделитель и сообщается как отдельный токен.

0 голосов
/ 24 марта 2011

Вы сказали, что не хотите повышения, так что ...

Возможно, это странный подход для использования в C ++, но я использовал его в MUD, где мне нужно было много токенизации в C.

возьмите этот блок памяти, назначенный для char * chars:

char chars [] = "Мне нравится возиться с памятью";

Если вам нужно токенизировать напробел:

create array of char* called splitvalues big enough to store all tokens
while not increment pointer chars and compare value to '\0'
  if not already set set address of splitvalues[counter] to current memory address - 1
     if value is ' ' write 0 there
       increment counter

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

подход такой:

  • итерация строки и указатель начала обновления токена обновления при первом появлении
  • конвертирует символ, который вам нужно разделить, в нули, которые означают завершение строки в C
  • , подсчитайте, сколько раз вы делали это

PS.Не уверен, что вы можете использовать подобный подход в жестких условиях Юникода.

0 голосов
/ 24 марта 2011

Привет, вы можете использовать wcstok функция

...