Help fixing file input reading routine?

S

sherifffruitfly

Hi - I'm just learning basic file i/o stuff, and the following input
routine skips the first entry in text files. I would guess it's a
similar phenomenon as when there's a CR left in the buffer and you need
to do a cin.get() to clear it. But I really don't know. Lil help?

Another thing: I initially wanted to use the conditional-? operator
inline in the cout statement at the end. Doing so never worked
(compiles fine, just gives incorrect answers). Why is this?

The test file I used contained only "1 2 3 4 5 6 7 8 9 10" (without
quotes). Runs always left the 1 out of the loop value cout.

TIA!

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

const int SIZE = 60;
const int FILESIZEMAX = 1000;

int main()
{
char filename[SIZE];
ifstream inFile;

cout << "File name: ";
cin.getline(filename,SIZE);

inFile.open(filename);

if (!inFile.is_open())
{
cout << "Couldn't open " << filename << endl;
cout << "Terminating execution\n";
exit(EXIT_FAILURE);
}

double value;
double sum = 0.0;
int count = 0;
double avg = 0.0;

inFile >> value;

while (inFile.good() && count<FILESIZEMAX)
{
++count;
sum += value;
inFile >> value;
cout << value << endl;
}

if (inFile.eof())
{
cout << "End of file reached\n";
}
else if (inFile.fail())
{
cout << "Data mismatch.\n";
}
else
{
cout << "Input terminated for unknown reason.\n";
}

cout << "Items read: " << count << endl;
cout << "Sum: " << sum << endl;

avg = count !=0 ? sum/count: 0.0;

cout << "Average: " << avg << endl;
cout << endl;

inFile.close();

return 0;
 
M

Marcus Kwok

Hi - I'm just learning basic file i/o stuff, and the following input
routine skips the first entry in text files. I would guess it's a
similar phenomenon as when there's a CR left in the buffer and you need
to do a cin.get() to clear it. But I really don't know. Lil help?

Another thing: I initially wanted to use the conditional-? operator
inline in the cout statement at the end. Doing so never worked
(compiles fine, just gives incorrect answers). Why is this?

The test file I used contained only "1 2 3 4 5 6 7 8 9 10" (without
quotes). Runs always left the 1 out of the loop value cout.
[snip]

int main()
{
char filename[SIZE];
ifstream inFile;

cout << "File name: ";
cin.getline(filename,SIZE);

inFile.open(filename);

if (!inFile.is_open())
{
cout << "Couldn't open " << filename << endl;
cout << "Terminating execution\n";
exit(EXIT_FAILURE);
}

double value;
double sum = 0.0;
int count = 0;
double avg = 0.0;

inFile >> value;

Here, you read in the first value from the file.
while (inFile.good() && count<FILESIZEMAX)
{
++count;
sum += value;
inFile >> value;

Here, you read in the second, third, fourth, etc. values from the file.
The first value you read in above is now gone.
cout << value << endl;
}

Better would be to do the reading in the loop condition:

while ((count < FILESIZEMAX) && (inFile >> value))
{
// ...
}
avg = count !=0 ? sum/count: 0.0;

cout << "Average: " << avg << endl;

Try:

cout << "Average: " << ((count != 0) ? sum / count : 0.0) << endl;

I find that using the ternary operator (x ? y : z) directly in output
statements requires extra sets of parentheses, probably due to the
relative precedence of the "<<" and the "?:" operators.
 
S

sherifffruitfly

I find that using the ternary operator (x ? y : z) directly in output
statements requires extra sets of parentheses, probably due to the
relative precedence of the "<<" and the "?:" operators.

Thanks! Worked like a charm!
while ((count < FILESIZEMAX) && (inFile >> value))

Question about the loop-reading-variable-assigment combo though. I
assume the stream assignment in the while condition is cast as a
boolean or something similar? does the cast-assignment have exactly the
same truth conditions as my original inFile.good condition? If you
don't have a quick and snappy answer, that's cool - I can go look that
up somewhere...

Thanks for the tips!
 
M

Marcus Kwok

Please do not erase the attribution lines, so that people can see who
wrote what. I have added it back in.

Question about the loop-reading-variable-assigment combo though. I
assume the stream assignment in the while condition is cast as a
boolean or something similar?

Almost, see:
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.4
does the cast-assignment have exactly the
same truth conditions as my original inFile.good condition? If you
don't have a quick and snappy answer, that's cool - I can go look that
up somewhere...

I'm not certain if it's *exactly* the same, but in pretty much all cases
it should do what you want. As far as I have seen, it is a "correct"
idiomatic C++ way of reading input though.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top