Public Group

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

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

## 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 C++ Primer 2nd Edition 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:
--------------------------------------------------------------
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:
--------------------------------------------------------------
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 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 on other sites
Quote:
 Random site returned by Googlecin.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 on other sites
I'm not sure, but I think the break is only breaking from the switch...

##### Share on other sites
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 on other sites
Whack in a breakpoint somewhere in the while loop, then use your compiler's debugger to watch the value of ch.

##### Share on other sites
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 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 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:
nothingnothingnothingnothing
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 nothingd nothingd nothingd nothingd nothingn nothingreached
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 on other sites
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.

1. 1
Rutin
32
2. 2
3. 3
4. 4
5. 5

• 13
• 9
• 9
• 9
• 14
• ### Forum Statistics

• Total Topics
633317
• Total Posts
3011338
• ### Who's Online (See full list)

There are no registered users currently online

×