Question:
I need help with a C program.?
Mike
2012-03-13 20:06:26 UTC
For the program below I am supposed to get the output:
Computer-> Please Enter a new Sequence:
User-> 34+
Computer-> (3) + (4) = (7)
Computer-> Please Enter a new Sequence:

but my output is:
Computer-> Please Enter a new Sequence:
User-> 34+
Computer-> (3) + (4) = (7)
Computer-> Please Enter a new Sequence:
Computer-> (3) + (4) = (7)
Computer-> Please Enter a new Sequence:

The output repeats.

#include
#include

void evaluate(int line[]);

main()
{
int line[3];

while (1) /* runs continually unless '#' is entered */
{
int c, i;

printf("Please enter a new sequence: \n");

for (i = 0; i < 3 && (c = getchar()) && c != '\n'; i++) /* loop initializes the array with two digits and an operator */
{
if (c == '#') /* no more sequences */
break;
else
line[i] = c;
}

if (c == '#')
break;

evaluate(line); /* function call */
}

printf("Good bye!\n");
}

void evaluate (int line[]) /* evaluates and displays the answer to the postfix expression */
{
int firstOp, secondOp, answer;

switch (line[0]) /* makes sure there is a number, assigns it to the local variable */
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
firstOp = line[0] - 48; /* turns the ascii value for the int into an int value */
break;
default:
printf("Not an integer\n");
break;
}

switch (line[1]) /* makes sure there is a number, assigns it to the local variable */
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
secondOp = line[1] - 48; /* turns the ascii value for the int into an int value */
break;
default:
printf("Not an integer\n");
break;
}

switch (line[2]) /* makes sure there is an operator, then computes the sum/difference/product/quotient */
{
case '+':
answer = firstOp + secondOp;
break;
case '-':
answer = firstOp - secondOp;
break;
case '*':
answer = firstOp * secondOp;
break;
case '/':
answer = firstOp / secondOp;
break;
default:
printf("Illegal operator\n");
break;
}

printf("(%d) %c (%d) = (%d)\n", firstOp, line[2], secondOp, answer); /* displays the sum */

}
Four answers:
John H
2012-03-13 21:35:06 UTC
Perhaps you didn't know that in the expression:



for (i = 0; cond_A && cond_B && cond_C; i++)



that cond_B will not be evaluated if cond_A is false. In C, evaluation ends early once the result can be determined. If cond_A is false, there is no need to calculated cond_B or cond_C, and in fact, the C language spec requires that cond_B not be evaluated in that case. That's why you see stuff like:



if (p && (*p==1))



if evaluation didn't end once p was known to be NULL, you'd be dereferencing a NULL pointer.



Back to your problem. When i is incremented from 2 to 3, the loop stops, but the "c = getchar()" has not been executed. So you have the old input in line[], and evaluate() gets called again.



What you did is ugly. Move the "c = getchar()" and the test of c into the body of the loop. Also check that c is not EOF.
Daniel
2012-03-14 03:49:55 UTC
Hi, I have fixed your error. Please read over what I have done and make sure you understand it before you submit it.



First, and some teachers grade on this while others do not, but it is always a good habit.



INDENTATION!!!



If you are using vim or vi, try the gg=G command to automatically indent the whole file.



1) (almost) Never put your variable declarations inside of a loop. They are getting reallocated every time you execute and this can cause some big overhead when you have a lot of them.



2) Dynamic - Instead of just letting the user enter 2 chars, use a do while loop and check for an exit condition. You can see this on line 16.



3) In any function it is always good practice to "return." In your main you had it set to break.



4) In c it is always good practice to clear stdin (what you read from the keyboard). This is done using fflush(stdin). I don't think you would have the issue in this program, but make it habit because with messy input things can get left behind.



5) With that said, here is your updated code. Please let me know if you have any questions.



#include

#include

#include

void evaluate(int line[]);



main()

{

int line[3];

int c, i;

while (1) /* runs continually unless '#' is entered */

{



printf("Please enter a new sequence: \n");

i = 0 ;

do {

fflush(stdin) ;

c = getchar() ;

if (c != '\n' && c != '#') line[i] = c ;

i++ ;

if (c == '#') break;

} while (c != '\n') ;





evaluate(line); /* function call */

}



if (c == '#') return ;



printf("Good bye!\n");

}



void evaluate (int line[]) /* evaluates and displays the answer to the postfix expression */

{

int firstOp, secondOp, answer;



switch (line[0]) /* makes sure there is a number, assigns it to the local variable */

{

case '0':

case '1':

case '2':

case '3':

case '4':

case '5':

case '6':

case '7':

case '8':

case '9':

firstOp = line[0] - 48; /* turns the ascii value for the int into an int value */

break;

default:

printf("Not an integer\n");

break;

}



switch (line[1]) /* makes sure there is a number, assigns it to the local variable */

{

case '0':

case '1':

case '2':

case '3':

case '4':

case '5':

case '6':

case '7':

case '8':

case '9':

secondOp = line[1] - 48; /* turns the ascii value for the int into an int value */

break;

default:

printf("Not an integer\n");

break;

}



switch (line[2]) /* makes sure there is an operator, then computes the sum/difference/product/quotient */

{

case '+':

answer = firstOp + secondOp;

break;

case '-':

answer = firstOp - secondOp;

break;

case '*':

answer = firstOp * secondOp;

break;

case '/':

answer = firstOp / secondOp;

break;

default:

printf("Illegal operator\n");

break;

}



printf("(%d) %c (%d) = (%d)\n", firstOp, line[2], secondOp, answer); /* displays the sum */

return ;

}
James Bond
2012-03-14 03:55:47 UTC
include

#include



void evaluate(int line[]);



main()

{

char line[4];



while (1) /* runs continually unless '#' is entered */

{





printf("Please enter a new sequence: \n");

scanf("%s",line);



if (line[2] == '#') break;

evaluate(line); /* function call */

}



printf("Good bye!\n");

}



void evaluate (int line[]) /* evaluates and displays the answer to the postfix expression */

{

int firstOp, secondOp, answer;



if(isdigit(line[0])) firstOp = line[0] - 48; /* turns the ascii value for the int into an int value */

else

printf("Not an integer\n");



if(isdigit(line[1])) secondOp = line[1] - 48; /* turns the ascii value for the int into an int value */

else

printf("Not an integer\n");



switch (line[2]) /* makes sure there is an operator, then computes the sum/difference/product/quotient */

{

case '+':

answer = firstOp + secondOp;

break;

case '-':

answer = firstOp - secondOp;

break;

case '*':

answer = firstOp * secondOp;

break;

case '/':

answer = firstOp / secondOp;

break;

default:

printf("Illegal operator\n");

break;

}



printf("(%d) %c (%d) = (%d)\n", firstOp, line[2], secondOp, answer); /* displays the sum */



}
2012-03-14 05:25:04 UTC
@Daniel:



1) Nope. If you do some tests with a decent compiler, you'll find that they're allocated only when the function is called. It's generally good practice to define certain variables within the body of a loop - that way you lower the amount of variable names that can be used outside of it.



3) main's return type is int, grandpa.



4) fflush only works on output (and update) streams, grandpa. Passing an input stream to fflush results in undefined behaviour.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...