>> ch = cin.get();
you should use infine, not cin
ch = infile.get();
And thanks for taking the time to read the board's rules to use code tags correctly. Not many first-time posters do that.
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
Off topic, but in the spirit of trying not to learn bad habits, and trying to avoid bugs that can be difficult to find when trying to determine why you don't get the results you expect on trial runs with known input as you test your code, the following
while (! infile.eof())
{
ch = cin.get();
could be changed to
while(infile >> ch)
You should avoid using the return value of eof() as the controlling condition for a loop. There are two reasons I know of to want to do this.
First, using the return value of eof() to terminate the loop is likely to cause a double counting of the last char in the file. If that char is a newline, then the double count will go unnoticed in your current code. But if the file terminates with an alphabetical char, it may, or may not, be counted twice. Inmy experience, trying to figure out why the code works appropriately sometimes and not others is probably the hardest bug to find.
Second, using the return value of the input statement to control the loop allows the loop to terminate appropriately, whether it terminates becuase it read the entire file, or whether it terminates because of some other cause. The loop might not terminate appropriately if the control condition is only whether the EOF marker was found but the linput stream fails for some other reason.
Lerner
Nearly a Posting Maven
2,382 posts since Jul 2005
Reputation Points: 739
Solved Threads: 396
You should avoid using the return value of eof() as the controlling condition for a loop. There are two reasons I know of to want to do this.
First, using the return value of eof() to terminate the loop is likely to cause a double counting of the last char in the file. If that char is a newline, then the double count will go unnoticed in your current code. But if the file terminates with an alphabetical char, it may, or may not, be counted twice. Inmy experience, trying to figure out why the code works appropriately sometimes and not others is probably the hardest bug to find.
That would be feof( ) you are talking about which returns zero only *after* the end of file is reached and not *when* the end of file is reached. eof( ) is actually good and returns a boolean value when the end of file is reached.
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
That would be feof( ) you are talking about which returns zero only *after* the end of file is reached and not *when* the end of file is reached. eof( ) is actually good and returns a boolean value when the end of file is reached.
No I believe eof has similar problems when the file contains extra newlines.
Like lerner and ravalon said best to avoid it altogether, especially in c++. I'm surprised your little google groups didn't tell you that sos. Ha ha.
iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
I don't get it. :confused: eof() returns true if the eofbit is set, but the eofbit doesn't get set until you hit end of file while reading. Unless you test for end of file after the read, the order is wrong and you'll loop one too many times.
My bad, I should have been more explicit. Yes, I agree, feof( ) and eof( ) are not that great when compared to checking the stream state while reading files. But for small fixes I normally use:
#include <fstream>
#include <iostream>
#include <string>
int main()
{
using namespace std;
// Build a test file
{
ofstream os( "test.txt" );
os << "12345";
}
// Test the test file :)
ifstream is( "test.txt" );
int loopCount = 0;
char ch;
while (1 ) {
is.get( ch );
if( is.eof() ) break ;
++loopCount;
cout << ch << '\n';
}
cout << "Loop count: " << loopCount << '\n';
getchar( ) ;
return 0;
}
I'm surprised your little google groups didn't tell you that sos. Ha ha.
*sigh* Btw when are you turning 14 ?
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
But for small fixes I normally use:
while ( 1 ) {
is.get( ch );
if( is.eof() ) break ;
++loopCount;
cout << ch << '\n';
}
Why that instead of this? Seems like more for less.:?:
while ( is.get( ch ) ) {
++loopCount;
cout << ch << '\n';
}
This will break the loop on errors too.
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
Yes, I agree, feof( ) and eof( ) are not that great when compared to checking the stream state while reading files. But for small fixes I normally use:
As always, in these circumstances go for the solution that works every time. Sure you can build functionality in eof() so that it works correctly.
Hell you can even use gets() safely if you go outta your way to implement the requisite error checks.
But that's extra work for very little benefit.
See you don't learn this at the google groups.:lol:
iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
As always, in these circumstances go for the solution that works every time. Sure you can build functionality in eof() so that it works correctly.
Hell you can even use gets() safely if you go outta your way to implement the requisite error checks.
But that's extra work for very little benefit.
The code snippet / my post was meant to illustrate that using eof( ) is not completely wrong or taboo if used the right way. Just ignoring a part of language just because using it in the wrong way ensues chaos is foolishness.
An use of eof( ) would be:
char buf[BUFSIZE];
do {
in.read( buf, BUFSIZE );
std::streamsize n = in.gcount();
out.write( buf, n );
} while( in.good() );
if( in.bad() || !in.eof() ) {
// fatal error occurred
}
in.close();
Not bad, is it...
So stop considering a feature bad just because someone says so... See you don't learn this at the google groups.I guess you were badly flamed at google groups for obvious reasons, thats why you keep mentioning it.....
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
An use of eof( ) would be:
char buf[BUFSIZE];
do {
in.read( buf, BUFSIZE );
std::streamsize n = in.gcount();
out.write( buf, n );
} while( in.good() );
if( in.bad() || !in.eof() ) {
// fatal error occurred
}
in.close();
Whydiscard the good/bad result and then call another function later to get a good/bad result? That is, why not this?
char buf[BUFSIZE];
while ( in.read( buf, sizeof buf ) )
{
out.write( buf, in.gcount() );
}
if ( in.bad() || !in.eof() )
{
// fatal error occurred
}
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
Nobody said to ignore it, just that there may be problems if you use it that way. ;)
Exactly. No one saideof() was bad. They just said while (!xx.eof()) is the wrong way to use it.That form won't work in most cases. You used it properly. The OP didn't.
WaltP
Posting Sage w/ dash of thyme
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
char buf[BUFSIZE];
do {
in.read( buf, BUFSIZE );
std::streamsize n = in.gcount();
out.write( buf, n );
} while( in.good() );
if( in.bad() || !in.eof() ) {
// fatal error occurred
}
in.close();
One problem with the above code is that when end-of-file is reached and write() will be executed with 0 data to write, such depending on implementation, might in worse case cause an exception.
I agree with the others that its best to avoid using eof() or feof(). There are other more efficient ways to code a loop like that.
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
There is acutally a typo in your program -- in your second loop while displaying, you have wrongly used and incremented the variable "i" when it should have been j. The result being that "j" never gets changed and results in an infinite loop.
Some tips:
• Avoid forward declaring the loop control variables since its better if you declare and initialize the loop control variable in the loop itself.
for( int i = 0; i < SIZE; ++i ) { // code }
• Your floating casting which happens in the second display loop is superfluous since it has no effect -- the values are in the end rounded off to integers. Better come up with a integer scaling factor which would greatly simplify the problem rather than coming up with cryptic calculations.
• Avoid delaring variables in loops. Though modern compilers have become really smart and perform a lot of optimizations, its better not to test its patience and write good code. Peform varaiable declarations just before the point of using them.
Something like:
for(int i = 0; i <26; i++)
{
length = count[i] ;
cout << static_cast<char>('a' + i) << ": " ;
for (int j = 0; j < length; j++)
{
cout << "* " ;
}
putchar( '\n' ) ;
}
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
for(i = 0; i <26; i++)
{
int length;
int j;
length = ((count[i] * 80)/(float)394);
for (j = 0; j < length; i++)
{
cout << "=" << endl;
}
return 0;
}
}
the last part is where im dumbingly trying to add it to my output. all that gets prints out is = signs that seem to loop forever. any help would be great guys.
Look carefully at your 2for loops... Do you see a mismatch of variables?
And is your return where you want it?
WaltP
Posting Sage w/ dash of thyme
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944