Используя strtok со станд.:: строка

45
задан Flexo 24 July 2012 в 16:56
поделиться

8 ответов

#include <iostream>
#include <string>
#include <sstream>
int main(){
    std::string myText("some-text-to-tokenize");
    std::istringstream iss(myText);
    std::string token;
    while (std::getline(iss, token, '-'))
    {
        std::cout << token << std::endl;
    }
    return 0;
}

Или, как упомянуто, повышение использования для большей гибкости.

61
ответ дан Community 26 November 2019 в 21:04
поделиться
  1. , Если повышение доступно в Вашей системе (я думаю, что это стандартно на большинстве дистрибутивов Linux в эти дни), это имеет Токенизатор класс, который можно использовать.

  2. В противном случае тогда быстрый Google поднимается скрученный вручную токенизатор для станд.:: строка, которую можно, вероятно, просто скопировать и вставить. Это очень коротко.

  3. И, если Вам не нравится ни один из тех, тогда вот, является разделение () функцией, которую я записал для создания моей жизни легче. Это повредит строку в части с помощью любого из символов в "delim" как разделители. Части добавляются к вектору "частей":

    void split(const string& str, const string& delim, vector<string>& parts) {
      size_t start, end = 0;
      while (end < str.size()) {
        start = end;
        while (start < str.size() && (delim.find(str[start]) != string::npos)) {
          start++;  // skip initial whitespace
        }
        end = start;
        while (end < str.size() && (delim.find(str[end]) == string::npos)) {
          end++; // skip to end of word
        }
        if (end-start != 0) {  // just ignore zero-length strings.
          parts.push_back(string(str, start, end-start));
        }
      }
    }
    
20
ответ дан Todd Gamblin 26 November 2019 в 21:04
поделиться

Копируйте строку, маркируйте ее, затем освободите ее.

char *dup = strdup(str.c_str());
token = strtok(dup, " ");
free(dup);
15
ответ дан DocMax 26 November 2019 в 21:04
поделиться

Я предполагаю, что язык является C или C++...

strtok, IIRC, заменяют разделители \0. Это - то, что это не может использовать строку константы. К обходному решению, что "быстро", если строка не огромна, Вы можете просто strdup () оно. Который мудр, если необходимо сохранить строку неизменной (что константу предлагают...).

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

1
ответ дан PhiLho 26 November 2019 в 21:04
поделиться

Предположение, что "строкой" Вы говорите о станд.:: строка в C++, Вы могли бы взглянуть на Токенизатор пакет в Повышение .

1
ответ дан Sherm Pendley 26 November 2019 в 21:04
поделиться

РЕДАКТИРОВАНИЕ: использование константы бросило, [только 119] раньше демонстрировали эффект strtok(), когда относится указатель, возвращенный строкой:: c_str ().

Вы не должны использовать strtok() , так как это изменяет маркируемую строку, которая может привести к нежелательному, если не неопределенный, поведение, поскольку струна до "принадлежит" строковому экземпляру.

#include <string>
#include <iostream>

int main(int ac, char **av)
{
    std::string theString("hello world");
    std::cout << theString << " - " << theString.size() << std::endl;

    //--- this cast *only* to illustrate the effect of strtok() on std::string 
    char *token = strtok(const_cast<char  *>(theString.c_str()), " ");

    std::cout << theString << " - " << theString.size() << std::endl;

    return 0;
}

После вызова к strtok(), пространство было "удалено" из строки или выключено к непечатаемому символу, но длина остается неизменной.

>./a.out
hello world - 11
helloworld - 11

Поэтому необходимо обратиться к собственному механизму, дублированию строки или сторонней библиотеки, как ранее упомянуто.

1
ответ дан philant 26 November 2019 в 21:04
поделиться

Прежде всего я сказал бы токенизатор повышения использования.
, Кроме того, если Ваши данные являются пространством, разделенным тогда, строковая потоковая библиотека очень полезна.

, Но оба вышеупомянутого были уже покрыты.
Поэтому как третья Подобная C альтернатива я предлагаю копировать станд.:: строка в буфер для модификации.

std::string   data("The data I want to tokenize");

// Create a buffer of the correct length:
std::vector<char>  buffer(data.size()+1);

// copy the string into the buffer
strcpy(&buffer[0],data.c_str());

// Tokenize
strtok(&buffer[0]," ");
0
ответ дан Martin York 26 November 2019 в 21:04
поделиться

There is a more elegant solution.

With std::string you can use resize() to allocate a suitably large buffer, and &s[0] to get a pointer to the internal buffer.

At this point many fine folks will jump and yell at the screen. But this is the fact. About 2 years ago

the library working group decided (meeting at Lillehammer) that just like for std::vector, std::string should also formally, not just in practice, have a guaranteed contiguous buffer.

The other concern is does strtok() increases the size of the string. The MSDN documentation says:

Each call to strtok modifies strToken by inserting a null character after the token returned by that call.

Но это неверно. Фактически функция заменяет первое вхождение символа-разделителя на \ 0. Никаких изменений в размере строки. Если у нас есть такая строка:

один-два --- три - четыре

мы получим

один \ 0two \ 0 - три \ 0-четыре

So my solution is very simple:


std::string str("some-text-to-split");
char seps[] = "-";
char *token;

token = strtok( &str[0], seps );
while( token != NULL )
{
   /* Do your thing */
   token = strtok( NULL, seps );
}

Read the discussion on http://www.archivum.info/comp.lang.c++/2008-05/02889/does_std::string_have_something_like_CString::GetBuffer

6
ответ дан 26 November 2019 в 21:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: