Strange output in loop

R

riva

#include <iostream>
using namespace std;

int main(void)
{
int i=0;
while(char c = cin.get() != EOF) {
i++;
cout << i << c << endl;
}
}

I am a C programmer and I am learning C++ from Thinking in C++.
The problems with the above code are:
1) i is incremented twice and the output is printed twice.
2) c is not printed.
 
J

Joe Greer

#include <iostream>
using namespace std;

int main(void)
{
int i=0;
while(char c = cin.get() != EOF) {
i++;
cout << i << c << endl;
}
}

Well, the problem is that you are assigning c the value of the comparison
between cin.get() and EOF. I am sure this isn't what you want. Try:

#include <iostream>
using namespace std;

int main()
{
int i=0;
char c;

while ((c = cin.get()) != EOF) {
i++;
cout << i << c << endl;
}
}

joe
 
I

Ioannis Gyftos

#include <iostream>
using namespace std;

int main(void)
{
int i=0;
while(char c = cin.get() != EOF) {
i++;
cout << i << c << endl;
}

}

I am a C programmer and I am learning C++ from Thinking in C++.
The problems with the above code are:
1) i is incremented twice and the output is printed twice.
2) c is not printed.

And your question is?

You probably mean something like
while(
(c = std::cin.get()) != EOF
) { ... }

Without the parentheses, you compare std::cin.get() with EOF, and
assign the result of the comparison to c. Then, c will contain some
sort of boolean representation, which is usually not printable (\0,
\1, or whatever).
 
J

Justin Spahr-Summers

Well, the problem is that you are assigning c the value of the comparison
between cin.get() and EOF. I am sure this isn't what you want. Try:

. . .
char c;

while ((c = cin.get()) != EOF) {
. . .

If 'char' is unsigned on a given implementation, this comparison could
lead to some odd behavior, as EOF is guaranteed to be negative (which
is why many I/O functions that handle single characters take and
return values of type int).
 
J

James Kanze

#include <iostream>
using namespace std;
int main(void)
{
int i=0;
while(char c = cin.get() != EOF) {
i++;
cout << i << c << endl;
}
}
I am a C programmer and I am learning C++ from Thinking in C++.

Are you a C programmer? The problems with the above code would
be problems in C as well.
The problems with the above code are:
1) i is incremented twice and the output is printed twice.
2) c is not printed.

The first problem with the above code is that EOF is out of band
information; cin.get() (like fgetc()) returns an int, not a
char, so that it can represent this information, as well as all
characters. So you need to declare c to be an int, and later
cast it to char once you've determined that it isn't EOF.

The second problem is that you're trying to do too much in one
statement, and getting confused about the precedences. It would
be far better to write the above:

int
main()
{
int i = 0 ;
int c = std::cin.get() ;
while ( c != EOF ) {
++ i ;
std::cout << i << static_cast< char >( c ) << std::endl ;
c = std::cin.get() ;
}
return EXIT_SUCCESS ;
}

By doing one thing at a time, you avoid obfuscation, and ensure
the correct ordering. (The correct ordering can also be ensured
by parentheses, but that doesn't do anything for the
obfuscation.)

A more typical C++ idiom, however, would be to use the status of
the istream to detect EOF:

int i = 0 ;
char c ;
while ( std::cin.get( c ) ) {
++ i ;
std::cout << i << c << std::endl ;
}

It's probably a matter of taste which one you use, but I think
the second is more idiomatic for C++ (where as long time C
programmers like myself still tend to use the first a lot).
 

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,772
Messages
2,569,593
Members
45,111
Latest member
VetaMcRae
Top