Reverse Polish Notation Troubleshooting in C - c

The question being asked is to evaluate RPN expressions and have the = be the terminating character of the sequence so that the program runs the RPN and calculates the expression it is given. So what I'm having some trouble with is understanding how I should convert my characters to integers as the instructions specifically say use scanf("%c", &ch) which pulls the input in as characters and not ints. How would I convert my characters to ints so I can push them to the array and do the operations on them accordingly?
//
// input: 1 2 3 * + =
// output: 7
//
#include <stdio.h>
#include <stdlib.h>
int collection[100];
int top;
void push(double v){
if (top>99)
{
printf ("Stack Overflow\n");
exit(0);
}
collection[++top]=v;
}
double pop(){
double v;
if(top < 0)
{
printf("stack underflow\n");
exit(0);
}
v=collection[--top];
return v;
}
int main(void){
char ch;
double a,b,c,sum;
int i;
top=-1;
printf("Enter an RPN expression: ");
while(ch!='='){
scanf("%c", &ch);
i=0;
c=1;
push(ch);
if(collection[i]=='+'){
a=pop();
b=pop();
c=b+a;
push(c);
}
else if(collection[i]=='-'){
a=pop();
b=pop();
c=b-a;
push(c);
}
else if(collection[i]=='*'){
a=pop();
b=pop();
c=b*a;
push(c);
}
else if(collection[i]=='/'){
a=pop();
b=pop();
c=b/a;
push(c);
}
else{
while(collection[i]!=0){
i++;
}
i=i-1;
sum=0;
while(i>=0){
sum=sum+((collection[i]-48)*c);
c=c*10;
i--;
}
push(sum);
}
}
printf("%lf\n",c);
}

If satisfied with unsigned int digits:
char ch;
scanf( "%c", &ch );
ch -= '0';
Then you can compose the number from digits by multiplying by 10 and adding the next digit.

Use double atof(const char *nptr);
The atof() function converts the initial portion of the string pointed
to by nptr to double. Although your programming structure in giving commands to the calculator is bad. Use separate functions for each task in algorithm to avoid complications
Here is (some of) my RPN calculator:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "cal.h"
#define MAXOP 100
int main(){
int type;
double op2,op3;
char s[MAXOP];
while((type = getop(s)) != EOF){
switch(type){
case NUMBER:
push(atof(s));
break;
case 'x':
op2 = pop();
op3 = pop();
push(op2);
push(op3);
break;
case 'o':
clear();
break;
case 's':
push(sin(pop()));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op2 = pop();
push(pop() - op2);
break;
case '/':
op2 = pop();
push(pop() / op2);
break;
case '%':
op2 = pop();
push((int)pop() % (int)op2);
break;
case '\n':
printf("\t%.4g\n",showtop());
break;
default:
printf("What was that?\n");
break;
}
}
return 0;
}

Related

Reading character-by-character - always reaching an invalid character

I'm new to C and to the programming world. I've been requested to get a reversed number in base 20 and print out his conversion to decimal.
I know it's not the most efficient code out there, but that's the best I managed to do with my current knowledge.
When I run this program and input a number, I'm always getting the default case...
What am I missing?
Thank you :)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
char x;
int exponent= 1;
int sum = 0;
int flag = 0;
printf("Enter a reversed number is base 20\n");
scanf(" %c", &x);
while (x != "\n") {
switch (x) {
case '0':sum += 0;
break;
case '1':sum += 1 * exponent;
break;
case '2': sum += 2 * exponent;
break;
case '3':sum += 3 * exponent;
break;
case '4':sum += 4 * exponent;
break;
case '5':sum += 5 * exponent;
break;
case '6':sum += 6 * exponent;
break;
case '7':sum += 7 * exponent;
break;
case '8':sum += 8 * exponent;
break;
case '9':sum += 9 * exponent;
break;
case 'A':
case 'a': sum += 10 * exponent;
break;
case 'B':
case 'b':sum += 11 * exponent;
break;
case 'C':
case 'c' : sum += 12 * exponent;
break;
case 'D':
case 'd': sum += 13 * exponent;
break;
case 'E':
case 'e': sum += 14 * exponent;
break;
case 'F':
case 'f': sum += 15 * exponent;
break;
case 'G':
case 'g': sum += 16 * exponent;
break;
case 'H':
case 'h': sum += 17 * exponent;
break;
case 'I':
case 'i': sum += 18 * exponent;
break;
case 'J':
case 'j': sum += 19 * exponent;
break;
default:flag++;
break;
}
if (flag == 1) {
printf("Error! %c is not a valid digit in base 20", x);
break;
}
else {
exponent *= 20;;
scanf("%c", &x);
}
}
if (flag == 1)
return 0;
else
printf(sum);
return 0;
}
You should really read your compiler's warnings...:
<source>: In function 'main':
<source>:10:14: warning: comparison between pointer and integer
10 | while (x != "\n") {
| ^~
<source>:10:14: warning: comparison with string literal results in unspecified behavior [-Waddress]
<source>:77:16: warning: passing argument 1 of 'printf' makes pointer from integer without a cast [-Wint-conversion]
77 | printf(sum);
| ^~~
| |
| int
In file included from <source>:2:
/usr/include/stdio.h:332:43: note: expected 'const char * restrict' but argument is of type 'int'
332 | extern int printf (const char *__restrict __format, ...);
| ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
You're comparing x to a an address - the address of the string constant "\n" (that is located in some section of your program's memory space). You probably meant to compare x to '\n'.
Also, the printf() function takes a format string before the argument, so it should be printf("%d\n", sum); (to also print a newline character).
PS 1: Always compile your code with more warnings turned on, e.g. gcc -W -Wall (and perhaps other warning flags) for a better chance catch these kinds of typos and minor errors.
PS 2: As #Jabberwocky notes, your program could be made much shorter (with no loss of readability); and, on the other hand, you should always check the return value of scanf() and similar functions which may fail due to user input:
#include <stdio.h>
#include <stdlib.h>
int main() {
char x;
int exponent = 1;
int sum = 0;
int num_scanned;
printf("Enter a reversed number is base 20\n");
num_scanned = scanf(" %c", &x);
if (num_scanned != 1) {
fprintf(stderr, "Invalid input\n");
exit(EXIT_FAILURE);
}
while (x != '\n') {
int digit;
if (x >= '0' && x <= '9') { digit = x-'0'; }
else if (x >= 'a' && x <= 'j') { digit = x-'a'; }
else if (x >= 'A' && x <= 'J') { digit = x-'A'; }
else {
fprintf(stderr, "%c is not a valid digit in base 20.", x);
exit(EXIT_FAILURE);
}
sum += digit * exponent;
exponent *= 20;
num_scanned = scanf("%c", &x);
if (num_scanned != 1) {
fprintf(stderr, "Invalid input\n");
exit(EXIT_FAILURE);
}
}
printf("%d\n",sum);
return EXIT_SUCCESS;
}

Why can't my calculator program calculate operator / aka. divsision properly?

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void run_calc();
void scandata(char *op, double *operand);
void do_next_op(char op, double operand, double *sum);
int main()
{
run_calc();
return 0;
}
void run_calc(){
double sum, operand;
char op, answer;
printf("Press enter to use the calculator\n");
scanf("%c", &answer);
while(answer!='q'&& answer!='Q')
{
printf("Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program.");
scandata(&op, &operand);
do_next_op(op, operand, &sum);
printf("Result so far is: %1.2lf \n", sum);
}
}
void scandata(char *op, double *operand) {
scanf(" %c", op);
if(*op =='+' || op == '-' || op == '*' || op =='/' || op =='^' ){
scanf ("%lf", operand);
}
}
void do_next_op(char op, double operand, double *sum)
{
switch(op)
{
case '+': *sum += operand; break;
case '-': *sum -= operand; break;
case '*': *sum *= operand; break;
case '/': *sum = (operand == 0) ? *sum : *sum / operand; break;
case '^': *sum = pow(*sum,operand); break;
case '#': *sum = (*sum >= 0) ? sqrt(*sum) : *sum; break;
case '%': *sum *= *sum -1; break;
case '!': *sum = (1 / *sum); break;
case '#': *sum = log(*sum); break;
case 'q': printf(" The final value of akku is %1.2lf \n", *sum); exit(0); defult: break;
}
}
Here is the conversaton when i input /2 which should give me 5 but it give me 2
Press enter to use the calculator
Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program.+5
Result so far is: 5.00
Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program.+5
Result so far is: 10.00
Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program./2
Result so far is: 2.00
Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program.Result so far is: 2.00
Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program.
How can i make it calculate correctly? and if an user input /0, i want the program to just print Result so far of sum, if not then just *sum/operand.
I think i did it right but i cant see the issue here. can someone help me?
In this line
if(*op =='+' || op == '-' || op == '*' || op =='/' || op =='^' ){
You dereferenced op to compare with '+', but didn't dereference that to compare with other things.
Have it dereference for the other operators will improve the behavior.
if(*op =='+' || *op == '-' || *op == '*' || *op =='/' || *op =='^' ){

Variable not Updating, While Loop not working

I am working on an accumulator that asks for different inputs and based on those inputs, updates values in an accumulator. My loop however, doesn't seem to run when I ask for a decimal, hexadecimal, or octal to be inputed. Could someone possibly take a look and give some suggestions to fix it? Thank you! Also Im suppose to somehow use a while loop in my print_menu() function that will check is the input is valid. Any suggestions?
#include <stdio.h>
#include <string.h>
short get_operand(char mode);
void print_acc(short acc);
char print_menu(void);
int main(void);
int main(){
char mode = 'D';
short acc = 8;
char input[10];
char option;
char valid_input[7] = "OHDCSQ";
while (mode != 'Q'){
print_acc(acc);
print_menu();
scanf("%s", &input);
printf("%s\n", input);
option = (char) toupper(input[0]);
switch(option){
case 'O':
mode = 'O';
printf("mode\n");
printf("Mode is Octal\n");
break;
case 'H':
mode = 'H';
printf("Mode is Hexadecimal\n");
break;
case 'D':
mode = 'D';
printf("Mode is Decimal\n");
break;
case 'C':
acc = 0;
break;
case 'S':
get_operand(mode);
if (mode == 'H'){
scanf("%hx", &acc);
printf("%hx", acc);
print_acc(acc);
}
else if (mode == 'O'){
scanf("%ho", &acc);
printf("%ho", acc);
print_acc(acc);
}
else{
scanf("%hd", &acc);
printf("%hd", acc);
print_acc(acc);
}
case 'Q':
mode = 'Q';
printf("\n");
break;
}
//return acc;
}
}
void print_acc(short acc){
printf("\n");
printf("****************************************\n");
printf("* Accumulator: *\n");
printf("* Hex : %04hx *\n", acc);
printf("* Octal : %08ho *\n", acc);
printf("* Decimal : %06hd *\n", acc);
printf("****************************************\n");
}
char print_menu(void){
printf("\n");
printf("Please Select one of the following options:\n");
printf("O Octal Mode\n");
printf("H Hecadecimal Mode\n");
printf("D Decimal Mode\n");
printf("\n");
printf("C Clear Accumulator\n");
printf("S Set Accumulator\n");
printf("\n");
printf("Q Quit\n");
printf("\n");
printf("Option: ");
}
short get_operand(char mode){
switch(mode){
case 'H':
printf("Enter Hex value:");
break;
case 'O':
printf("Enter Octal value:");
break;
default:
printf("Enter decimal value: ");
break;
}
return mode;
}
In the 'S' case where you read in a number, you forget to add a break statement at the end of the case. This results in the code falling through to the Q case which causes the loop to exit.
Add the break and the loop will continue as expected:
case 'S':
...
break;
case 'Q':
...
This is also incorrect:
scanf("%s", &input);
%s expects a char *, but you're passing the address of an array (a char (*)[10] to be presice). Pass in the array directly, which will decay to a pointer to the first element to yield the correct type:
scanf("%s", input);
Also, change print_menu and get_operand to return void, since you're not using the return value and in the former case failing to include one.

C - while loop hanging on the condition

I'm a newbie learning code so this might be pretty simple but I can't understand what is happening.
When I try to run the following code it seems to hang on the while loop condition and doesn't execute any code after that. Is the != operator not suited for this?
I also tried a do {} while and everything ran fine but as soon as I set the operator to 'E', again the condition seems to hang there and doesn't get out of the loop.
#include <stdio.h>
int main(void) {
float n, content;
char operator;
n = content = 0;
operator = 'a';
printf("Begin Calculations:\n");
while (operator != 'E');
{
scanf("%f %c", &n, &operator);
switch (operator) {
case 's':
case 'S':
content = n;
printf("= %f\n", content);
break;
case '+':
content = content + n;
printf("= %f\n", content);
break;
case '-':
content = content - n;
printf("= %f\n", content);
break;
case '*':
content = content * n;
printf("= %f\n", content);
break;
case '/':
content = content / n;
printf("= %f\n", content);
break;
case 'e':
case 'E':
printf("End of calculations\n");
operator == 'E';
break;
default:
printf("Invalid input\n");
break;
}
}
return 0;
}
Remove the semicolon at the end of the while statement:
while(operator != 'E')
{
The semicolon ends the body of the while statement, in other words it behaves as if you would write this:
while(operator != 'E')
{
}
causing an infinite loop.
You need to remove the semi-colon at the end of while
You need to take into account both cases
So change
while(operator != 'E');
to
while(operator != 'E' && operator != 'e')
You have a classic bug in your while loop:
while (operator != 'E');
{
The ; after the condition is parsed as en empty statement, hence your while runs forever if operator is different from 'E'.
Using the classic Kernighan and Ritchie brace style makes this kind of bug obvious and much less likely to occur:
while (operator != 'E') {
Also note that you should exit your loop from the switch statement instead of testing for E in the while condition, this would allow for both e and E to be handled correctly (your statement operator == 'E'; is a no op, it should be written operator = 'E';. Also check the return value of scanf to avoid looping endlessly at end of file.
Here is an improved version:
#include <stdio.h>
int main(void) {
float n, content;
char operator;
int active = 1;
n = content = 0;
printf("Begin Calculations:\n");
while (active && scanf("%f %c", &n, &operator) == 2) {
switch (operator) {
case 's':
case 'S':
content = n;
printf("= %f\n", content);
break;
case '+':
content = content + n;
printf("= %f\n", content);
break;
case '-':
content = content - n;
printf("= %f\n", content);
break;
case '*':
content = content * n;
printf("= %f\n", content);
break;
case '/':
content = content / n;
printf("= %f\n", content);
break;
case 'e':
case 'E':
printf("End of calculations\n");
active = 0;
break;
default:
printf("Invalid input\n");
break;
}
}
return 0;
}
while(operator != 'E');
The correct syntax is while (...) { ... } without semicolon or do { ... } while (...); with.
printf("End of calculations\n");
operator == 'E';
The assignment operator is a single =. Change == into = and it should be fine.
You need to remove the semi-colon from while loop because semi-colon means end of statement so your program is not executing further
couple of things.
1- operator is a reserve word, you should change the variable name
2- (semicolon ;) after while()
Check update code:
#include <stdio.h>
int main(void)
{
float n, content;
char operator1;
n = content = 0;
operator1 = 'a';
printf("Begin Calculations:\n");
while(operator1 != 'E')
{
scanf("%c", &operator1);
switch(operator1)
{
case 's':
case 'S':
content = n;
printf("= %f\n", content);
break;
case '+':
content = content + n;
printf("= %f\n", content);
break;
case '-':
content = content - n;
printf("= %f\n", content);
break;
case '*':
content = content * n;
printf("= %f\n", content);
break;
case '/':
content = content / n;
printf("= %f\n", content);
break;
case 'e':
case 'E':
printf("End of calculations\n");
operator1 = 'E';
break;
default:
printf("Invalid input\n");
break;
}
}
return 0;
}

RPN calculator using push and pop.

I want to design a RPN calculator using push and pop. But I am not getting the right result for e after running the program. It seems that c and d are storing 0 after I use pop() to get the value of a and b from the stack. Any suggestions?
#include <stdio.h>
int stack[50];
int first = 0;
int main(void){
int a,b,c,d,e;
char opr[4];
printf("Enter 2 numbers \n");
scanf("%d",&a);
scanf("%d",&b);
void push(int x); // Calling the push function
int pop(); // Calling the pop function
push(a);
push(b);
printf("Enter the operator \n");
scanf("%s",&opr[4]);
switch(opr[4]){
case '+': c=pop(); d=pop(); e=c+d; break;
case '-': c=pop(); d=pop(); e=c-d; break;
case '*': c=pop(); d=pop(); e=c*d; break;
case '/': c=pop(); d=pop(); e=c/d; break;
default: printf("not a valid option");
}
push(e);
printf("%d",e);
printf("%d",stack[50]);
return 0;
}
void push(int x){
if(first==50){
printf("The stack is full");
}else{
x = stack[first];
first++;
}
}
int pop(){
int y;
if(first == 0){
printf("Stack is empty ");
}else{
first--;
y = stack[first];
return y;
}
}

Resources