Rainmaker's blog

By Rainmaker, 12 years ago, In English

In C++, one can make string handling lot simpler using strings and string steam class.

I used to take a lot of time thinking how we should take the input from the user, at times I needed the whole line to be a part of the string, and there were times when I wished only the characters till the next space would be entered in the string.

So, heres a brief tutorial for me for scanning the whole line/ part of the string from the user.

1. Scanning the whole line:

consider the line you want to scan is:

you are my pumpkin pumpkin, hello honey bunny!

Now, if you just do

string S;
cin >>S ;
cout << S;

you will get just

you

as your output. To get the whole string as an input, use the following line:

string S;
getline(cin,S);
cout << S;

you get the whole line scanned in S.

2. tokenizing the scanned line

using stringstream class would help tokenize the string.

use the following::

 #include<sstream>
 
 stringstream SS;
 string s,s1;
 getline(cin, s);
 SS << s;
 do{
     s1.erase(); // to remove all characters from s1.
     SS >> s1;
 cout << s1 << endl;
 }while(SS);
 
 SS.str("");    // to reuse the stringstream object.

Hope this helps!

  • Vote: I like it
  • +8
  • Vote: I do not like it

| Write comment?
»
12 years ago, # |
Rev. 2   Vote: I like it +25 Vote: I do not like it

2.

 #include<sstream>
 
 string s,s1;
 getline(cin, s);
 stringstream SS(s);
 while (SS >> s1) 
   cout << s1 << endl;
 }
»
12 years ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

There is one pitfall with getline(). Suppose the input is of form "an integer n, then n lines follow":

3
abc
def
ghi

It would seem that this code will work:

int n; vector<string> arr;

cin >> n;
arr.resize(n);
for (int i = 0; i < n; i++)
    getline(cin, arr[i]);

But afterwards, arr[0] will contain an empty string and all other strings will be off by one. This is because the first getline() considers the newline after n to be the string that we want to read. The solution is to skip whitespace explicitly with ws:

int n; vector<string> arr;

cin >> n >> ws;
arr.resize(n);
for (int i = 0; i < n; i++)
    getline(cin, arr[i]);
  • »
    »
    4 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); is more convenient way to skip characters until next line.

»
12 years ago, # |
  Vote: I like it +12 Vote: I do not like it

Special for fans of char*:

#include <cstdio>

char *t, s[1000], word[1000];
int add;

gets(s);
for (t = s; sscanf(t, "%s%n", word, &add) == 1; t += add)
  puts(word);

P.S. If you have question "why not strtok?": for this task — why not, but in general sscanf can more.