#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;
}
Или, как упомянуто, повышение использования для большей гибкости.
, Если повышение доступно в Вашей системе (я думаю, что это стандартно на большинстве дистрибутивов Linux в эти дни), это имеет Токенизатор класс, который можно использовать.
В противном случае тогда быстрый Google поднимается скрученный вручную токенизатор для станд.:: строка, которую можно, вероятно, просто скопировать и вставить. Это очень коротко.
И, если Вам не нравится ни один из тех, тогда вот, является разделение () функцией, которую я записал для создания моей жизни легче. Это повредит строку в части с помощью любого из символов в "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));
}
}
}
Копируйте строку, маркируйте ее, затем освободите ее.
char *dup = strdup(str.c_str());
token = strtok(dup, " ");
free(dup);
Я предполагаю, что язык является C или C++...
strtok, IIRC, заменяют разделители \0. Это - то, что это не может использовать строку константы. К обходному решению, что "быстро", если строка не огромна, Вы можете просто strdup () оно. Который мудр, если необходимо сохранить строку неизменной (что константу предлагают...).
, С другой стороны, Вы могли бы хотеть использовать другой токенизатор, возможно, скрученный вручную, менее сильный на данном аргументе.
Предположение, что "строкой" Вы говорите о станд.:: строка в C++, Вы могли бы взглянуть на Токенизатор пакет в Повышение .
РЕДАКТИРОВАНИЕ: использование константы бросило, [только 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
Поэтому необходимо обратиться к собственному механизму, дублированию строки или сторонней библиотеки, как ранее упомянуто.
Прежде всего я сказал бы токенизатор повышения использования.
, Кроме того, если Ваши данные являются пространством, разделенным тогда, строковая потоковая библиотека очень полезна.
, Но оба вышеупомянутого были уже покрыты.
Поэтому как третья Подобная 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]," ");
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