Sign in to follow this  

Stays in loop, but it's not an infinite loop...

This topic is 4530 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 learned C two or so years ago, and I recently (last year) decided to teach myself cxx. I never got around to doing it until now. So I have this book called [u]C++ Primer 2nd Edition[/u] by Stanley B. Lippman. Exercise 0-3 tells me to write a program that will count the amount of blanks, tabs, newlines, and characters (without white spaces) of an input. Few pages earlier it gave a similar program:
/*
*This program reads a character at a time from standard input
*until end-of file is encountered.  It keeps a count of both the number of
*characters and the number of lines it reads.  Its output is of the following form:
*	lineCount characterCount
#include <iostream.h>

int main ()
{
	char ch;
	int lineCnt=0, charCnt=0;
	
	while(cin.get(ch))
	{
		switch(ch)
		{
			case '\t':
			case ' ':
				break;
			case '\n':
				++lineCnt;
				break;
			default:
				++charCnt;
				break;
		}
	}
	cout<<lineCnt<<" "<<charCnt<<endl;
	return 0;
}
So I based my program off of that (hey, if it's given, I'll take it):
#include <iostream.h>

int main ()
{
	char ch;
	int lineCnt=0, charCnt=0, tabCnt=0, blankCnt=0;
	
	while(cin.get(ch))
		switch(ch)
		{
			case '\t':
				++tabCnt;
				break;
			case ' ':
				++blankCnt;
				break;
			case '\n':
				++lineCnt;
				break;
			default:
				++charCnt;
				break;
		}
	cout<<"\t\tTotal Characters: "<<charCnt<<"\n\n\nLines:   "<<lineCnt<<"\nChars:   "<<charCnt<<"\nTabs:    "<<tabCnt<<"\nBlanks: "<<blankCnt<<endl;
	return 0;
}
The output is as follows(I typed in "hello"):
EXECUTING:
/home/[username removed]/C++/Exercis0.3/Count
--------------------------------------------------------------
hello
And it just stays there... I asked my friend (been cxx programming for ~2.5 years now), and his initial thought was that it was in an infinite loop. I saw it as a possibility, but I didn't see why it would be stuck in an infinite loop, so I ran a test:
#include <iostream.h>

int main ()
{
	char ch;
	int lineCnt=0, charCnt=0, tabCnt=0, blankCnt=0;
	
	while(cin.get(ch))
	{
		switch(ch)
		{
			case '\t':
				++tabCnt;
				cout<<"t";
				break;
			case ' ':
				++blankCnt;
				cout<<"b";
				break;
			case '\n':
				++lineCnt;
				cout<<"n";
				break;
			default:
				++charCnt;
				cout<<"d";
				break;
		}
		cout<<" nothing\n";
	}
	cout<<"reached\n";
	cout<<"\t\tTotal Characters: "<<charCnt<<"\n\n\nLines:   "<<lineCnt<<"\nChars:   "<<charCnt<<"\nTabs:    "<<tabCnt<<"\nBlanks: "<<blankCnt<<endl;
	return 0;
}
The output is as follows (I typed in "hello"):
EXECUTING:
/home/[username removed]/C++/Exercis0.3/Count
--------------------------------------------------------------
hello
d nothing
d nothing
d nothing
d nothing
d nothing
n nothing
As you can see it never leaves the while loop, but it's not an infinite loop. What is going on? Just tell me that, and I might be able to solve the problem on my own.

Share this post


Link to post
Share on other sites
Read the comment at the top of the Lippman program. Under what condition does the loop terminate? Has that condition been met?

Share this post


Link to post
Share on other sites
Quote:
Random site returned by Google
cin.get() performs a blocking read for the next character

It appears the while loop is waiting for cin.get() to return, but it never will because it's blocking until it gets more input.

EDIT: Sneftel beat me to it; I suppose EOF will cause cin.get() to fail and return false.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
correct; breaks within the switch statement will only break out of the switch; the while loop continues until cin.get returns false -> either EOF, or a read error has occurred. so, to end the program and get the character counts you desire, press Ctrl+D (linux; might work for windows cmd, i wouldn't be the person to ask)

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
ctrl+c or ctrl+z is the windows key for feeding a null (and therefore an end of file). Had to do the same sort of thing in Java a while back.

~Savagemonitor

Share this post


Link to post
Share on other sites
Here is what I would do:
1) Change #include <iostream.h> to #include <iostream> and put using namespace std ; after all includes.
2) add in a done variable, so that the beginning of your loop looks like this:
while(cin.get(ch) && done == 0)

3) now, tweak it so that when the user presses a certain key (say 'q'), done will equal 1 and the loop will exit and display how many tabs, spaces, etc.


Just a question, not really related to this, why do you call C++ cxx?

Share this post


Link to post
Share on other sites
First, I'll repeat myself. It's not out of the loop, but that doesn't make it an infinite loop. To my knowledge (using the checks) it's no longer in the loop. Other wise it would always repeat:
nothing
nothing
nothing
nothing
And on and on and on (infinite loop). But it's not. In fact, you know it's not out of the the loop because it doesn't output:
d nothing
d nothing
d nothing
d nothing
d nothing
n nothing
reached
that "reach" would indicate it's no longer in the loop.

Oberon_Command, you are correct about using the flag, but I don't want any special characters because that could cause it to terminate "unexpectedly" (on the front-end).

I ran another test, this time on the user side. After writing "hello" and it did it's thing, I wrote "something" and found that it went through everything again. So it's in the loop, but it's not really an infinite loop. I had my mom help me out...

Thanks though

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
cin.get(ch) is waiting for you to enter text. That is why the while loop never terminates. In order to terminate the while loop, you have to input an end-of-file character. End-of-file causes cin.get(ch) to return false, so the loop condition will not be met and it will terminate.

End-of-file is either CTRL-D or CTRL-Z depending on what system you're on.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Also, cin.get(char) is an I/O blocking function, meaning that if the input stream (cin) is empty, which it is after "hello" has been processed, the function waits for user input, essentially "blocking" the program from continuing until some input arrives in the stream. In your case, you want to input end-of-file to terminate the loop.

Share this post


Link to post
Share on other sites
Alternatively, you could run it with the standard input redirected from a file via the command line. Assume you compile "counter.exe": make a text file "test.txt" with test input, and then run the program -

C:\path\to\exe>counter < test.txt

Share this post


Link to post
Share on other sites

This topic is 4530 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this