• Advertisement
Sign in to follow this  

is it wrong? : simple C++ question

This topic is 3456 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been going going back over C++ after taking a course in C++ and Java a month or two ago. I've been messing around in Java but I figured it was time to go back to C++ and work up to using APIs and getting off console programs. But
#include <iostream>
#include <string>
using namespace std;

int main()
{
    string word;
    
    while ( cin >> word )
		cout << "word read is: " << word << "\n";
	
	cout << "ok: no more words to read: bye!\n";
    return 0;
}
According to my book (C++ Primer) this should output when I type in: " riverrun, past Eve and Adam's "
word read is: riverrun,
word read is: past
word read is: Eve
word read is: and
word read is: Adam's
word read is: ok: no more words to read: bye!
I get everything except the last line. The loop obviously never ends, it just sits there and waits for more words to be entered. According to the book its right, but I don't see how. Is there a typo or am I missing something?

Share this post


Link to post
Share on other sites
Advertisement
I'm not too experienced with C++ but I think that your problem is this:

cin >> word does not return a boolean value therefore your condition is automatically evaluated as true running the loop for ever.

Share this post


Link to post
Share on other sites
Try this:


while ( cin >> word && word != "quit" )
cout << "The word is: " << word << "\n";



...with " riverrun, past Eve and Adam's quit "

Share this post


Link to post
Share on other sites
I agree with you, but my book does not.


string word;
while ( cin >> word )
// ...

reads one string from standard input with each iteration of the while loop until all the strings are read. The condition

( cin >> word )

evaluates to false when the end-of-file is reached...


I'm not one to argue with a book, I don't know enough to like pretty much see it and know if it's wrong. Anyone know if I'm missing something or the segment is just wrong?

Share this post


Link to post
Share on other sites
[Heh, two people posted in while I was writing.]

You COULD change that to

while( cin >> word, word != exitValue )

I used things like this a lot in school, but not so much anymore. It's not really the safest code you could write, but it works.

The comma operator makes it so the first statement runs, then is forgotten for the second. The above suggestion of using &&, however, catches a few problems I never cared to worry about.

jdub:
> cin >> word does not return a boolean value

Well...filestreams actually return a void pointer via implicit conversion when inside if statements (zero for bad stream, non-zero for file opened). Maybe cin does something like that as well. Not that my own testing showed that was the case, though.

Share this post


Link to post
Share on other sites
Quote:
Original post by _fastcall
Try this:

*** Source Snippet Removed ***

...with " riverrun, past Eve and Adam's quit "



Yeah, that works but I just don't understand how the book could miss something like that. Oh well, I'll just chalk it up to bad editing.

Thank you for the help.

Share this post


Link to post
Share on other sites
Quote:
Original post by sjmx22
Quote:
Original post by _fastcall
Try this:

*** Source Snippet Removed ***

...with " riverrun, past Eve and Adam's quit "



Yeah, that works but I just don't understand how the book could miss something like that. Oh well, I'll just chalk it up to bad editing.

Thank you for the help.
I don't think the book missed anything; in this case, operator>>() returns a reference to the input stream, and (as mentioned) the input stream can be implicitly converted to a boolean value, so the original code does in fact make sense as written.

You might give the text another read - it may be that you're supposed to enter an end-of-file code of some sort (e.g. ctrl-Z) to terminate the loop.

Share this post


Link to post
Share on other sites
perhaps hitting CTRL+C will set the stream to EOF and the conversion may yield false, but its been so long since I wrote console based programs, so try that.

Share this post


Link to post
Share on other sites
Yeah the code is correct. But it's assuming that you're going to type in an EOF character (this used to be common knowledge when UNIX was king).

Try ctrl+C or ctrl+D or ctrl+Z or something...

Share this post


Link to post
Share on other sites
This is the exact excerpt from the book. Doesn't mention anything about end of file code or terminating the loop.


The code sequence

string word;
while ( cin >> word )
// ...

reads one string from standard input with each iteration of the while loop until all the strings are read. The condition

( cin >> word )

evaluates to false when the end-of-file is reached (how this occurs is explained in Chapter 20). Here is a simple program that uses the code sequence:

#include <iostream>
#include <string>

int main()
{
string word;

while ( cin >> word )
cout << "word read is: " << word << '\n';

cout << "ok: no more words to read: bye!\n";
return 0;
}

The following are the first five words of James Joyce's novel Finnegans Wake:

riverrun, past Eve and Adam's

When these words are entered at the keyboard, the output of the program is as follows:

word read is: riverrun,
word read is: past
word read is: Eve
word read is: and
word read is: Adam's
word read is: ok: no more words to read: bye!



Quote:
Original post by Hodgman
Yeah the code is correct. But it's assuming that you're going to type in an EOF character (this used to be common knowledge when UNIX was king).

Try ctrl+C or ctrl+D or ctrl+Z or something...



Ctrl+C ends the program and cuts off the command line so it says,

wor^C

Ctrl+Z causes an endless loop that needs to be ended with ctrl+C and ctrl+D is a special character.


Ctrl+C seems to be what it needs, it definitely ends the loop but it can't output the full line.


I'm using Windows, not Unix. The book didn't specificly say, use UNIX and is usually worded with instructions for both. There wasn't a special instruction with this though.

Share this post


Link to post
Share on other sites
It looks like the book is wrong in what the expected output is. An input command should not just fail if there is no input ready, naturally it has to wait for more input. If it wasn't so you wouldn't even be able to input the sentence in the first place! (The book does mention end-of-file and that is what you have to type to get out of this loop.)

So, enter your sentence and push enter. After it has displayed the words, press Cntr+C and you should see the other message (unless you have "console closing" problems).

Share this post


Link to post
Share on other sites
as said before the book probably just made a mistake, and in my time of using books to help me learn to program i've come across many things that just didn't work the way the book said it should. and in alot of ways it helps you become a better programmer because you can learn from the mistakes other make and reminds us all that we can still make mistakes even if we are a guru of programming :)

Share this post


Link to post
Share on other sites
Quote:
Original post by sjmx22
This is the exact excerpt from the book. Doesn't mention anything about end of file code or terminating the loop.

Quote:

...reads one string from standard input with each iteration of the while loop until all the strings are read. The condition ( cin >> word ) evaluates to false when the end-of-file is reached (how this occurs is explained in Chapter 20).
Yes it does ;) It says the loop will terminate (because "cin>>word" is evaluated as false) once the end-of-file code is entered.

Perhaps chapter 20 explains how it wants you to enter the EOF code?


[EDIT] Wikipedia says that on windows, EOF is ctrl+Z.
If this is causing an endless loop, then your compiler might not be standards-compliant. Which compiler are you using?

[EDIT 2]I tried the code out (in MSVC 2005), and it's a bit picky about how you enter your input.

I had to type my sentence, then press return, then press ctrl+z, then press return again! It would be nice of the book to tell you this ;(
i like the rice [enter]
word read is: i
word read is: like
word read is: the
word read is: rice
^Z [enter]
ok: no more words to read: bye![/quote]

The output is also a bit different than the book predicted... Perhaps the book was written using a non-standard-compliant compiler?

Share this post


Link to post
Share on other sites
It should really work with Ctrl+Z. I just tested it (using VC++2008):

riverrun, past Eve and Adam's
word read is: riverrun,
word read is: past
word read is: Eve
word read is: and
word read is: Adam's
^Z
ok: no more words to read: bye!

Share this post


Link to post
Share on other sites
its in an infinite loop
try using a counter to quit loop after number of inputs

Share this post


Link to post
Share on other sites
Quote:
Original post by sas1992
its in an infinite loop


No. The loop will end as soon as reading from the input stream fails.

Share this post


Link to post
Share on other sites
VC++ 08

ctrl+z works, I don't know why but before when I tried it late last night it was just endless looping in the console, I was probably hitting the wrong thing. but it does work perfectly now.

It threw me when it said, "end-of-file is reached", I don't know that doesn't too me sound like you need to enter a special thing to tell it the end-of-file is reached but now I know.

Thank you for all your help, everyone.

Share this post


Link to post
Share on other sites
Hey, How about try this ...

#include <iostream>
#include <string>
using namespace std;

int main()
{
string word;

while ( cin >> word )
cout << "word read is: " << word << "\n";

cout << "ok: no more words to read: bye!\n";

int i; //use this to have a stop when it execute to here
cin >> i; // then your screen will not only flash and go to close

return 0;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by CloudShawChina
Hey, How about try this ...

#include <iostream>
#include <string>
using namespace std;

int main()
{
string word;

while ( cin >> word )
cout << "word read is: " << word << "\n";

cout << "ok: no more words to read: bye!\n";

int i; //use this to have a stop when it execute to here
cin >> i; // then your screen will not only flash and go to close

return 0;
}



Using system("Pause"); to halt console closure is also possible, and in my opinion, more readabe, understandable and correct.

Share this post


Link to post
Share on other sites
Quote:
Original post by sjmx22
It threw me when it said, "end-of-file is reached", I don't know that doesn't too me sound like you need to enter a special thing to tell it the end-of-file is reached but now I know.


My guess is that in a little bit, the book will show you file streams. If you're reading from a file and not from the console input, this code would be more natural (the EOF is automatically at the end of the file).

Share this post


Link to post
Share on other sites
Quote:
Original post by sjmx22
It threw me when it said, "end-of-file is reached", I don't know that doesn't too me sound like you need to enter a special thing to tell it the end-of-file is reached but now I know.


Despite what you might think in light of that, the 'end-of-file' is not an additional bit of data at the end of a file or stream. The end-of-file is just the end of a file: there's nothing there, not even a 'this file is over' tag.

When reading from a stream, when no more data can be read, the stream refuses to read anything and places itself in EOF state. In C++ programming terms, your input stream sets the EOF flag on itself because it has no more data to read.

However, in user terms, there are mostly three ways of sending data to a program through a stream (usually the standard input stream): either you pipe the output of another program, or you pipe a file, or you type the lines that should be sent to the program in the console window.

Piping the output of a program is usually expressed as firstprogram | secondprogram in most terminals. It copies all data from the first program's output stream to the second program's input stream. When the first program dies, the second program can read all that the first program has written to the stream, and attempting to read beyond that results in an end-of-file trigger on the stream. No 'end of stream' bit of data is sent between the programs: instead, the second program's read attempt just fails with an 'end of file' error.

Piping a file into a program is usuallyl expressed as program < file in most terminals. It sends all data from the file to the program, line by line, until there is no more data in the file, at which point it stops. The program accesses this data through its input stream, and once it has read all the data from the file, it stops. This is usually equivalent to piping the output of a program that reads a file and outputs it (such as cat file | program in most *NIX systems).

Finally, typing in the data directly will place an additional program between you (the user) and the program you are running. This additional program will read keys from you: all keypresses you send are placed in a string and left there, except two: a return character will be added to the string, and then the string will be sent to the standard input of your program, then cleared; and an end-of-transmission control character will send the remaining text to your program, and then kill the additional program. That's it: the end-of-transmission control character is not an end-of-file character appended to the data you send to your program, it's a special sequence that kills the additional program.

Share this post


Link to post
Share on other sites
Quote:
Original post by sjmx22
This is the exact excerpt from the book. Doesn't mention anything about end of file code or terminating the loop.


Yes, it does. I emboldened that part below:

Quote:


The code sequence

string word;
while ( cin >> word )
// ...

reads one string from standard input with each iteration of the while loop until all the strings are read. The condition

( cin >> word )

evaluates to false when the end-of-file is reached (how this occurs is explained in Chapter 20).
Here is a simple program that uses the code sequence:



The loop terminates when the expression controlling it evaluates to false. Thus, when there is "no more text" in standard input, the program knows it is done.

But we can't just type a line and have that be that. Normal programs accept multiple lines of input from the user, so the program can never read your mind and assume that you aren't going to type any more. We need an indicator that the input is done, which is the EOF character that Hodgman mentions.



Quote:

Ctrl+C ends the program and cuts off the command line so it says,

wor^C

Ctrl+Z causes an endless loop that needs to be ended with ctrl+C and ctrl+D is a special character.


Ctrl+C seems to be what it needs, it definitely ends the loop but it can't output the full line.


I'm using Windows, not Unix. The book didn't specificly say, use UNIX and is usually worded with instructions for both. There wasn't a special instruction with this though.


An unfortunate oversight.

Ctrl-C is common to Windows and Unix in this usage. The C stands for Cancel, and it's intended to end your program, dead in its tracks - not just the standard input.

Ctrl-D is the EOF character for Unix. It doesn't mean anything special to Windows.

Ctrl-Z should work for you. Try typing it at the end of the line, and then hitting return. What gets printed during your "endless loop"?

[Edited by - Zahlman on August 5, 2008 4:47:58 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by sjmx22
This is the exact excerpt from the book. Doesn't mention anything about end of file code or terminating the loop.


Yes, it does. I emboldened that part below:
It's already emboldened 9 posts up :P

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement