istream input loop

Hello. If you enter the wrong data in the code, for example, two words through a space, then the input is looped, the loop works and is not blocked where the "cin >> id >> name" instruction. This bug occurs on Linux and on Windows everything is correct. Tell me please what's the matter?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<iostream>
#include<string>

using namespace std;

int main()
{
	int id;
	string name;

	cout << "Please fill data: (int)id (string)name \n"
		"(press Ctrl+D to complete):";

	while (true) {
		if (cin >> id >> name) {
			cout << "Entered: " << id << ":" << name << "\n";
			continue;
		}

                // Ctrl+D
		if (cin.eof()) { break; } 

                // incorrect data format
		if (cin.fail()) {
			cerr << "Wrong data try again.\n";
			cin.clear();
			cin.ignore(cin.rdbuf()->in_avail());
		}

                // trace the stream state
		cerr << "in_avail" << cin.rdbuf()->in_avail() << "\n"; // 0
		cerr << "eof" << bool(cin.eof()) << "\n";   // 0
		cerr << "fail" << bool(cin.fail()) << "\n"; // 0
		cerr << "bad" << bool(cin.bad()) << "\n";   // 0
		cerr << "good" << bool(cin.good()) << "\n";   // 1
	}

	return 0;
}
Try this instead of your cin.ignore() line:
1
2
// #include <limits>
cin.ignore(numeric_limits<streamsize>::max(), '\n');

This says to ignore all characters up to and including the newline character.
Last edited on
1
2
// #include <limits>
cin.ignore(numeric_limits<streamsize>::max(), '\n');

Thanks a lot! It work! Please, can you explain what's wrong in my code, and why your code is work?
Last edited on
I'm not entirely sure why yours didn't work, but apparently in_avail() doesn't necessarily tell you how many characters are in the input (at least not on linux).

The replacement code works since instead of reading a specific number of characters, it just reads characters until it reads the newline.
Thanks again. All the best to you.
Topic archived. No new replies allowed.