1
int t;
cin>>t;
while(t--){

    string s;

    getline(cin,s);
    cout<<s.length()<<endl;
}

When I run the program after inputting t it immediately prints 0 when I press enter after input t. Rather what I want to have is take t then start getline inputs.

Manish Sharma
  • 142
  • 1
  • 11
  • possible duplicate of [cin and getline skipping input](http://stackoverflow.com/questions/10553597/cin-and-getline-skipping-input) – Mohit Jain Jun 08 '15 at 11:33

2 Answers2

0

Put cin.ignore before the loop and try again.

If there is a newline left in the stream, it will stop reading there.

Andreas DM
  • 10,685
  • 6
  • 35
  • 62
0

The most robust advice is to never mix formatted I/O (e.g. using operator >>) with line oriented input on the same stream (e.g. getline()) or with character oriented input (e.g. cin.get()).

The reason is that the different styles of input function respond to newlines differently. Formatted I/O tends to stop and leave a newline in the stream (where it will be encountered first up by getline() in your code) whereas line oriented input will tend to respond immediately to any newline and discard it.

So change cin >> t to

string temp_string;
getline(cin, some_string);
istringstream some_stream(some_string);   // from <sstream>
some_stream >> t;

The above can be placed in a separate function if you find yourself doing such things frequently.

When combined with the code in your loop, this will only ever interact directly with cin using line-oriented input, which will avoid the sort of confusion you are seeing.

Using tricks like cin.ignore() or stream manipulators (e.g. getline(cin << std::ws, s) will be fragile, depending on how other code (before or after yours) interacts with the stream.

Peter
  • 35,646
  • 4
  • 32
  • 74
  • I was just in the middle of writing something like this. – Avi Ginsburg Jun 08 '15 at 07:39
  • Great (and incurably modest) minds think alike, Avi. – Peter Jun 08 '15 at 07:40
  • I would add that the single exception that I've made is when the first part of a file is text (header) and the rest is binary. – Avi Ginsburg Jun 08 '15 at 07:41
  • In that case, I'd work with pure binary I/O, and extract the header and "rest" separately. Mixing binary I/O with other styles of input (character, line-oriented, formatted) is also fragile. – Peter Jun 08 '15 at 07:47
  • Fragile, but sometimes necessary/useful. – Avi Ginsburg Jun 08 '15 at 07:48
  • @Peter `.ignore` is for sure fragile and sensitive unless used carefully. `std::ws` on the other hand is not only foolproof but also recommended in this case. Moreover both `>>` and `getline` have well defined documented bahaviour, there is no issue in mixing these. Introducing `istringstream` in this case is unnecessary. Read [Keep it simple](http://en.wikipedia.org/wiki/KISS_principle) – Mohit Jain Jun 08 '15 at 08:02
  • Mohit: Your approach relies on the fictitious obedient user, who only inputs data in the exact form you describe. The `getline()/stringstream` approach will cope with real-world users who enter other characters (e.g. a `'` at the end of a line - which a user might easily do either deliberately or by accident). Your approach with manipulators will not. – Peter Jun 08 '15 at 09:06
  • @Peter what if the same practical user inputs empty newlines every now and then? – Mohit Jain Jun 08 '15 at 15:19
  • Depends on whether the program needs to handle the empty lines or not. If the program skips whitespace, it will skip any empty lines (or lines containing only whitespace) immediately after reading `t`, so those lines cannot be counted. With `getline()`, they can be if needed. – Peter Jun 09 '15 at 08:45