Есть ли встроенный способ разделения строк в C++?

ну что там? под строкой я подразумеваю std::string

Ответов (10)

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

Нет единого способа сделать это.

Я предпочитаю boost :: tokenizer , только его заголовок и простой в использовании.

Струны STL

Вы можете использовать итераторы строк для выполнения своей грязной работы.

std::string str = "hello world";

std::string::const_iterator pos = std::find(string.begin(), string.end(), ' '); // Split at ' '.

std::string left(str.begin(), pos);
std::string right(pos + 1, str.end());

// Echoes "hello|world".
std::cout << left << "|" << right << std::endl;

Вот функция разделения в стиле Perl, которую я использую:

void split(const string& str, const string& delimiters , vector<string>& tokens)
{
    // Skip delimiters at beginning.
    string::size_type lastPos = str.find_first_not_of(delimiters, 0);
    // Find first "non-delimiter".
    string::size_type pos     = str.find_first_of(delimiters, lastPos);

    while (string::npos != pos || string::npos != lastPos)
    {
        // Found a token, add it to the vector.
        tokens.push_back(str.substr(lastPos, pos - lastPos));
        // Skip delimiters.  Note the "not_of"
        lastPos = str.find_first_not_of(delimiters, pos);
        // Find next "non-delimiter"
        pos = str.find_first_of(delimiters, lastPos);
    }
}

Ответ - нет. Вы должны разбить их с помощью одной из библиотечных функций.

Что-то я использую:

std::vector<std::string> parse(std::string l, char delim) 
{
    std::replace(l.begin(), l.end(), delim, ' ');
    std::istringstream stm(l);
    std::vector<std::string> tokens;
    for (;;) {
        std::string word;
        if (!(stm >> word)) break;
        tokens.push_back(word);
    }
    return tokens;
}

Вы также можете взглянуть на basic_streambuf<T>::underflow() метод и написать фильтр.

void split(string StringToSplit, string Separators)
{
    size_t EndPart1 = StringToSplit.find_first_of(Separators)
    string Part1 = StringToSplit.substr(0, EndPart1);
    string Part2 = StringToSplit.substr(EndPart1 + 1);
}

Струны C

Просто вставьте \0 то место, которое хотите разделить. Это примерно настолько же встроено, насколько вы можете получить со стандартными функциями C.

Эта функция разбивается при первом появлении char разделителя, возвращая вторую строку.

char *split_string(char *str, char separator) {
    char *second = strchr(str, separator);
    if(second == NULL)
        return NULL;

    *second = '\0';
    ++second;
    return second;
}

Какого черта ... Вот моя версия ...

Примечание. Разделение на («XZaaaXZ», «XZ») даст вам 3 строки. 2 из этих строк будут пустыми и не будут добавлены в theStringVector, если IncludeEmptyStrings имеет значение false.

Разделитель - это не какой-либо элемент в наборе, а скорее соответствует этой строке.

 inline void
StringSplit( vector<string> * theStringVector,  /* Altered/returned value */
             const  string  & theString,
             const  string  & theDelimiter,
             bool             theIncludeEmptyStrings = false )
{
  UASSERT( theStringVector, !=, (vector<string> *) NULL );
  UASSERT( theDelimiter.size(), >, 0 );

  size_t  start = 0, end = 0, length = 0;

  while ( end != string::npos )
  {
    end = theString.find( theDelimiter, start );

      // If at end, use length=maxLength.  Else use length=end-start.
    length = (end == string::npos) ? string::npos : end - start;

    if (    theIncludeEmptyStrings
         || (   ( length > 0 ) /* At end, end == length == string::npos */
             && ( start  < theString.size() ) ) )
      theStringVector -> push_back( theString.substr( start, length ) );

      // If at end, use start=maxSize.  Else use start=end+delimiter.
    start = (   ( end > (string::npos - theDelimiter.size()) )
              ?  string::npos  :  end + theDelimiter.size()     );
  }
}


inline vector<string>
StringSplit( const  string  & theString,
             const  string  & theDelimiter,
             bool             theIncludeEmptyStrings = false )
{
  vector<string> v;
  StringSplit( & v, theString, theDelimiter, theIncludeEmptyStrings );
  return v;
}

Достаточно простым методом было бы использовать метод c_str () std::string для получения массива символов в стиле C, а затем использовать strtok () для токенизации строки. Не так красноречиво, как некоторые другие решения, перечисленные здесь, но это просто и работает.

Ага, струнный поток.

std::istringstream oss(std::string("This is a test string"));
std::string word;
while(oss >> word) {
    std::cout << "[" << word << "] ";
}