Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use getline and while loop to split a string

Tags:

c++

for example i have a string:

string s = "apple | orange | kiwi";

and i searched and there is a way:

stringstream stream(s);
string tok;
getline(stream, tok, '|');

but it only can return the first token "apple" I wonder that is there any way so it can return an array of string? Thank you. Let assume that the string s may be changed. For exammple, string s = "apple | orange | kiwi | berry";

like image 632
Xitrum Avatar asked Apr 22 '11 16:04

Xitrum


2 Answers

As Benjamin points out, you answered this question yourself in its title.

#include <sstream>
#include <vector>
#include <string>

int main() {
   // inputs
   std::string str("abc:def");
   char split_char = ':';

   // work
   std::istringstream split(str);
   std::vector<std::string> tokens;
   for (std::string each; std::getline(split, each, split_char); tokens.push_back(each));

   // now use `tokens`
}

Note that your tokens will still have the trailing/leading <space> characters. You may want to strip them off.

like image 193
Lightness Races in Orbit Avatar answered Nov 15 '22 21:11

Lightness Races in Orbit


Since there is space between each word and |, you can do this:

string s = "apple | orange | kiwi";
stringstream ss(s);
string toks[3];
string sep;
ss >> toks[0] >> sep >> toks[1] >> sep >> toks[2];

cout << toks[0] <<", "<< toks[1] <<", " << toks[2];

Output:

apple, orange, kiwi

Demo : http://www.ideone.com/kC8FZ

Note: it will work as long as there is atleast one space between each word and |. That means, it will NOT work if you've this:

string s = "apple|orange|kiwi";

Boost is a good if you want robust solution. And if you don't want to use boost for whatever reason, then I would suggest you to see this blog:

Elegant ways to tokenize strings

It explains how you can tokenize your strings, with just one example.

like image 20
Nawaz Avatar answered Nov 15 '22 21:11

Nawaz