tokenize a string

K

Kelvin@!!!

hi:
in C, we can use strtok() to tokenize a char*
but i can't find any similar member function of string that can tokenize a
string
so how so i tokenize a string in C++?
do it the C way?

thanks
 
R

red floyd

Kelvin@!!! said:
hi:
in C, we can use strtok() to tokenize a char*
but i can't find any similar member function of string that can tokenize a
string
so how so i tokenize a string in C++?
do it the C way?

thanks

Look up std::istringstream in your favorite reference book.
 
R

rossum

hi:
in C, we can use strtok() to tokenize a char*
but i can't find any similar member function of string that can tokenize a
string
so how so i tokenize a string in C++?
do it the C way?

thanks

There is a sample chapter from Accelerated C++ on the web at
http://www.awprofessional.com/articles/article.asp?p=25333

The chapter has a function called split() which does what you seem to
want, it takes a string and returns a vector of all the individual
words:

// true if the argument is whitespace, false otherwise
bool space(char c) { return isspace(c); }

// false if the argument is whitespace, true otherwise
bool not_space(char c) { return !isspace(c); }

vector<string> split(const string& str) {
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while (i != str.end()) {
// ignore leading blanks
i = find_if(i, str.end(), not_space);
// find end of next word
iter j = find_if(i, str.end(), space);
// copy the characters in [i, j)
if (i != str.end()) ret.push_back(string(i, j));
i = j;
}
return ret;
}

There is a detailed explanation of the functino in the text.

rossum
 
D

davidrubin

rossum said:
// true if the argument is whitespace, false otherwise
bool space(char c) { return isspace(c); }

// false if the argument is whitespace, true otherwise
bool not_space(char c) { return !isspace(c); }

vector<string> split(const string& str) {
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while (i != str.end()) {
// ignore leading blanks
i = find_if(i, str.end(), not_space);
// find end of next word
iter j = find_if(i, str.end(), space);
// copy the characters in [i, j)
if (i != str.end()) ret.push_back(string(i, j));
i = j;
}
return ret;
}

This would be better if it was templatized by an insertion iterator
rather than returning a vector by value. Something along the lines of
(untested)

template <typename InsertIter>
int
tokenize(const std::string& buf,
const std::string& delims,
InsertIter it)
{
std::string::size_type sp; // start position
std::string::size_type ep; // end position
int numTokens = 0;

do {
sp = buf.find_first_not_of(delims, sp);
ep = buf.find_first_of(delims, sp);
if (sp != ep) {
if (ep == buf.npos) {
ep = buf.length();
}
*it++ = buf.substr(sp, ep - sp);
++numTokens;
sp = buf.find_first_not_of(delims, ep + 1);
}
} while (sp != buf.npos);

if (sp != buf.npos) {
*it++ = buf.substr(sp, buf.length() - sp);
++numTokens;
}

return numTokens;
}

called as

std::deque<std::string> tokens;
int numTokens = tokenize(buf, delims, std::back_inserter(tokens));

/david
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top