Reputation: 47
I have a while loop reading in a char 'c', I have a check to see if the the char is an operator; '+', '-', '/', or '*'. The while loop reads through character by character but it doesn't stop...if the last char inputed is '+' for example. It will stay in the loop with the char 'c' set to '+' forever.
stack<int> num;
char c;
int n,count=0,a,b;
while (cin>>c)
{
if (c != '+' && c != '-' && c != '/' && c != '*')
{
cout << c << endl;
n = (c - 48);
num.push(n);
cin >> c;
count++;
}
else if (c == '+' || c == '-' || c == '/' || c == '*')
{
cout << "count is " << count << endl;
if (count>1)
{
b = num.top();
a = num.top();
num.pop();
num.pop();
if (c == '+')
{
num.push(a+b);
count--;
}
else if (c == '-')
{
num.push(a+b);
count--;
}
else if (c == '/')
{
if (b != 0)
{
num.push(a/b);
count--;
}
else
{
cout << "division by zero" << endl;
return(0);
}
}
else if (c == '*')
{
num.push(a*b);
count--;
}
else
{
cout << "invalid input" << endl;
return(0);
}
}
else
{
cout << "stack underflow" << c << endl;
return(0);
}
}
cout << c << endl;
}
}
Upvotes: 2
Views: 2087
Reputation: 381
This should work:
#include <cstdio>
...
int c; // As pointed out by James Kanze in his comment, c should be an int to detect EOF
do {
c = getchar();
// Do stuff
} while ((c != '\n') && c != EOF))
You don't need to check just for EOF, but also for the line terminator.
Upvotes: 1
Reputation: 153909
There are several problems with your code. For starters,
I don't understand the purpose of the cin >> c
in the if
branch; you input a character, but you never seem to use it;
it's just lost. And of course, there's no need for the if
part in the else if
, since it is the complement of the
condition of the if
. And of course, a switch
is far more
natural that you if/else if
chain when comparing a single
character against a number of different constants. And of
course, '0'
isn't always 48
(and even if it were, '0'
is
a lot more readable than 48
).
As for staying in the loop with the char c
set to +
, I don't
see it. The only loop I see is while( std::cin >> c )
, and
this will either read a new character, or terminate.
If your goal is to just read a single line, it's probably better
to use std::getline
, then iterate over the string you input:
std::string line;
while ( std::getline( std::cin, line ) ) {
// Set up your stack here...
for ( std::string::const_iterator it = line.begin(); it != line.end(); ++ it ) {
if ( isdigit( static_cast<unsigned char>( *it ) ) ) {
// process digit...
} else if ( ispunct( static_cast<unsigned char>( *it ) ) ) {
// process punctuation, with eventually
switch ( *it ) {
case '+':
// addition...
break;
case '-':
// substraction...
break;
// ...
default:
// illegal operator...
break;
}
} else {
// process anything else...
}
}
}
Alternatively, you can define an isOperator
function, along
the lines of:
bool
isOperator( char ch )
{
static std::string const legalOps( "+-*/" );
return std::find( legalOps.begin(), legalOps.end(), ch) != legalOps.end();
}
Upvotes: 1
Reputation: 7429
Now that you clarified your question it's way clearer. And @TeoZec answer should be right. I just wanna note two things that seem buggy in your above code:
else if (c == '-')
{
num.push(a+b);
count--;
}
here you probably wanted a-b
instead.
if (count>1)
{
b = num.top();
a = num.top();
num.pop();
num.pop();
b
and a
will be the same number here, you should call pop()
before getting the second number, like:
if (count>1)
{
b = num.top();
num.pop();
a = num.top();
num.pop();
Upvotes: 3
Reputation: 588
Its because you have no condition to terminate your while loop, you will need to add either more conditions to your while like so:
while(cin>>c && c != '+' && c != '-' && c != '*' && c != '/')
{
//do stuff here
}
Or add a break
to the inside of your while loop, after performing your checks to see what character was entered.
Upvotes: 1