Cin.eof () functionality

I understand that cin.eof() checks the stream format. And, giving input, the end of the character is not reached when there is an error at the input. I tested this on my MSV C ++ 2010 and don't understand the strange results. No matter what I give for input, I get a Format Error message that is present in the program.

 #include <iostream> using namespace std; int main() { int i; cin>> i; if(!cin.eof()) { cout<< "\n Format Error \n"; } else { cout<< "\n Correct Input \n"; } getchar(); return 0; } 

Expected results:

Values ​​for i =

  • 10 => Correct input, but output - Format error.
  • 12a => Format error

Can someone explain where I'm wrong. Thanks.

+6
c ++ iostream visual-c ++
source share
8 answers

std::cin.eof() tests for end-of-file (hence eof), and not for errors. To check for errors, use !std::cin.good() , the built-in conversion operator ( if(std::cin) ) or the logical negation operator ( if(!std::cin) ).

+14
source share

Use a direct stream status test with:

 while (cin >> i) { ... } 
+9
source share

For an input stream to enter the EOF state, you should try to read the end of the stream end. That is, it is not enough to get to the end of the stream in the stream, you really need to try to read the character after the end. This attempt will activate the EOF state, which in turn will make cin.eof() return true.

However, in your case, you not only do not do this, you (most likely) have not even reached the end of the stream. If you type your 10 from the keyboard, you probably finished typing by pressing the [Enter] key. This led to the addition of a newline character to the input stream. So, what you are actually parsing with the >> operator in this case is actually a 10\n sequence. Since you requested the int value from the stream, it reads only numeric characters from the stream, that is, it reads 1 and 0 , but stops at \n . This \n stays in the stream. You never read it. Thus, it is obvious that your code never reaches the end-of-file position in the stream. You should think that cin.eof() will become true in this case.

+3
source share
 #include <iostream> int main() { using namespace std; int i; if (cin >> i) { cout << "Extracted an int, but it is unknown if more input exists.\n"; char c; if (cin.get(c)) { // Or: cin >> c, depending on how you want to handle whitespace. cin.putback(c); cout << "More input exists.\n"; if (c == '\n') { // Doesn't work if you use cin >> c above. cout << "But this was at the end of this line.\n"; } } else { cout << "No more input exists.\n"; } } else { cout << "Format error.\n"; } return 0; } 

Also see Testing stream.good () or! stream.eof () reads the last line twice .

An example of a session with the above program, note that the input lines are marked with comments that are not in the actual output:

 $ your-program 12 # input Extracted an int, but it is unknown if more input exists. More input exists. But this was at the end of this line. $ your-program 12a # input Extracted an int, but it is unknown if more input exists. More input exists. $ echo -n 12 | your-program Extracted an int, but it is unknown if more input exists. No more input exists. $ your-program a # input Format error. 
+2
source share

Assuming your input is line-based, I suggest you read the entire line using std::getline() . When you have a string, you can parse it and decide if it contains correct or incorrect input. Put the line in std::istringstream and do the following:

Edit: Modified !! iss !! iss up to static_cast<bool>(iss) for compatibility with C ++ 0x.

 std::istringstream iss (line); char ch; long lval; // read the input iss >> lval; // result variable will contain true if the input was correct and false otherwise result // check that we have read a number of at least one digit length = static_cast<bool>(iss) // check that we cannot read anything beyond the value read above && ! (iss >> ch); 
+2
source share

Adding to the previous answer: After reading your input (for example, 10) you are not at the end of the file, as you can easily enter a little more. How does the system know that you will not?

When reading the second input (12a), it correctly reads all the digits that can be part of an integer. The letter 'a' cannot, therefore, it is left for some possible subsequent input. For example, you can read all parts of 12a with this code

int i; char c;

cin β†’ i β†’ c;

+1
source share

cin.eof() check if the stream has reached the end of the file, which occurs if you type something like Ctrl + C (on Windows) or if the input has been redirected to a file, etc.

To check if an input contains an integer and is nothing more than an integer, you can first enter the input into a string and then convert it with a string stream. The string stream really reaches eof if it no longer needs to be fetched from it.

 #include <iostream> #include <sstream> #include <string> int main() { using namespace std; int i; string input; cin >> input; //or getline(cin, input) stringstream ss(input); if (ss >> i && ss.eof()) { //if conversion succeeds and there no more to get cout<< "\n Correct Input \n"; } else { cout<< "\n Format Error \n"; } return 0; } 
+1
source share

EOF stands for e nd o f f . std :: cin - standard input. Standard input, under normal circumstances, never goes to the end: you can always just type in a little more.

In addition, .eof () returns true only if the input operation has already failed due to an attempt to read the end of the file. In fact, a program cannot say that it is "at the end of a file"; that is, the only way to know that the next attempt to read the data will fail, actually making an attempt.

0
source share

All Articles