This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 7 years ago.
I have a file containing only one character 1 (there is no newline symbol after it)
Reading the contents with this method:
int value;
ifstream in("somefile");
for (!in.eof())
{
in >> value;
cout << "input: " << value << " , eof" << in.eof() << "'\n";
}
gives me the following output:
input: 1 , eof: 0
input: 1 , eof: 1
The questions are:
1) Why EOF flag is not set after first reading try? I mean, if program successfully reads the number on the first try, it somehow knows that the string representatiion of it is over. To find it out it has to try read at least one byte after 1 character and there it should have hitted EOF. Why that doesn' happen?
2) That said, if I have a file with one value per line, I always do have a duplicate of last input. Does it mean that I always have to discard it in any way and that would be correct? Or for example add extra check for EOF after in >> value; and only if it succeeds, do any logic I want?
I know that I can work around with readline() or while(in >> value) methods but it's more a question of understanding what really happens there.
Thank you.
Related
This question already has answers here:
Change string by index
(3 answers)
Closed 7 years ago.
string l;
cin>>l[0];
cout<<l;
input:a
output:
According to me the code must print the value of l[0] but why is there no output?
You need to do
cin>>l;
In your current state of code, when you try to access l[0] you are trying to access a memory location which may or may not be there. cin >> l[0] doesn't changes the size of the string which remains 0.
So when you try to do cout << l you are effectively printing an empty string.
Another alternative is
string s;
s.resize(1);
You have an empty string. There are no characters in it, including 0th character, you trying to read into. You need to actually add characters in string:
std::string l;
l.push_back('\0'); //Or any other character
std::cin >> l[0];
This question already has an answer here:
Is it possible to read an empty string from cin and still get true from cin.good()?
(1 answer)
Closed 7 years ago.
I am following the C++ primer book, and got curious about the following code example:
string buf;
while (cin >> buf && !buf.empty()) {
if (buf[0] != '_')
continue; // get another input
//the input starts with an underscore; process buf . . .
}
The loop should ignore words that do not start with an underscore and do something with the ones that do start with an underscore.
My question is about the condition
(cin >> buf && !buf.empty())
I would say that the condition (!buf.empty()) is always true when (cin >> buf) is true, so I do not see the point of adding it.
Is there any case when the second condition is not redundant?
There is a previous question on stack overflow about a similar construction (Is it possible to read an empty string from cin and still get true from cin.good()?) whose answer is simply no (the second condition is redundant).
If this is correct, why is it on the book? It is simply an error?
Or there is some special situation were the double condition makes sense?
just to be clear, operator bool() is badbit || failbit, and the failbit is set when "an input operation failed to read the expected charchter or any other kind of operation failed to produce the desired result" (Langer, Kreft 1999)
string buf;
while ((cin >> buf,cin.operator bool()) && !buf.empty()) {
if (buf[0] != '_')
continue; // get another input
//the input starts with an underscore; process buf . . .
}
This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 9 years ago.
I am compiling the following code under Microsoft Visual Studio 2013
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream in("filename.txt");
int n;
while (!in.eof()) {
in >> n;
cout << n << endl;
}
return 0;
}
filename.txt contains:
4
note: the second line is empty line.
I am getting this output:
4
4
My question is: Why 4 is duplicated in the output when I add trailing spaces or empty lines to the end of the file? and why eof is not working properly in this case?
Using !eof(), !fail(), !bad(), or !good(), is invariably the wrong way to condition your input. The point is to perform the extraction first, and then check if succeeded. If you do the former, you'll almost always get the problems you are experiencing.
The first extraction into n obtained 4 from the stream. After it found the newline it stopped and you printed the value of n. When the second loop executed, the extractor cleared the leading whitespace from the stream (meaning the newline after 4), found the end of the stream and set eofbit. Since no characters were extracted, it also set failbit. When you attempted to print the value again, all you were seeing was the result of the previous input operation.
This isn't the right way to perform a read. You have to do it before checking the stream. This is how it is commonly done:
while (in >> n)
{
std::cout << n << std::endl;
}
After the read is performed, operator bool() will be invoked on the stream, which will access its stream state and determine if the extraction succeeded. If it did, only then will the loop body execute.
You aren't checking the state of the operation. Even if in >> n; sets a status of fail (so n was not set to a new value), you perform the next line. See http://www.cplusplus.com/doc/tutorial/files/ or http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/ or similar. Your file has an empty line before the eof, so you run the code in the while loop twice.
Here's what happens during the above code execution:
1st loop iteration:
read 4 into n
output n (4)
2nd loop iteration:
read EOF
(here there is no test for EOF)
output n (4)
3rd loop iteration (doesn't happen, because EOF was read during the last read)
You should be testing the state of in in your loop condition:
while (in >> n)
{
// all is good, carry on
}
This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 9 years ago.
Hi i currently wrote a program but I'm having problems with reading the file. It seems to have read the last line twice, as a result, producing the same results twice.
I had put the getline() function to read the first line, in order to store the string for the variable G.
The rest, I had stored it in a vector of the class object.
basically the file is opened and it performs this loop
file.open("bodies1.txt");
getline(file, G1);
....
while(!file.eof)
{
file >> body;
bodies.push_back(body);
}
this is what the text file look like (this is just a sample. not the actual thing)
0.02932
Sun 32 42 53 2 2
Moon 49 32 4 2 1
Jupiter 32 53 2 3 2
I really was wondering why it read the last line twice. Any suggestions?
while(!file.eof())
{
file >> body;
bodies.push_back(body);
}
After reading the last object in to body, eof is the next character. Then
file >> body;
tries to read it and fails. So whatever was in body before is still there and will be pushed in to the vector.
instead you should read like
while(file >> body)
{
bodies.push_back(body);
}
This way your while stops as soon as you encounter eof() and you will not do an extra push in to the vector.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is iostream::eof inside a loop condition considered wrong?
I was reading a group of characters via cin.get() and I noticed that my cin.get() was getting an exra character at the end of the input. Might anyone know how to fix this? Here's my code:
unsigned char c;
while(!cin.eof())
{
c = cin.get();
cout << (int)c << endl;
}
My issue is that the character it gets is one of 255 ascii value. I simply don't want it to get this extra character, but if the user enters in a ascii value of 255 without it being a garbage character at the end, then that should be fine. An example would be so for my output:
if I entered in abc\n in my output:
I get
97
98
99
10
255
but I want:
97
98
99
10
Any ideas on how to fix this? Thanks!
Never use cin.eof() as a loop condition. It almost always produces buggy code, as it has here.
Instead, try:
int c;
while ( (c=cin.get()) != EOF ) {
cout << c << endl;
}
Or:
char c;
while (cin.get(c)) {
cout << (int)c << endl;
}
The get() function with no arguments returns an int_type, not a char. At the end of the stream, it returns a special non-character value that indicates end of file (usually -1). By assigning the result of cin.get() directly to an unsigned char, you are inadvertently throwing away this eof information. The relevant documentation quote is:
1) reads one character and returns it if available. Otherwise, returns Traits::eof() and sets failbit and eofbit.