tags:

views:

253

answers:

1

I need to use getchar(), putchar() for I/O. My program works just fine but I cannot use it like it is in CodeWarrior for an embedded system. I also need to get rid of malloc() and just use a stack for pop/push. Can I still use strtol if I am no longer using scanf?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 10

float *p, *tos, *bos;
int *p2, *tos2, *bos2;
int imode = 1;      

void push(float f); float pop(void);
void push2(int i); int pop2(void);

int main (void) {

    float a, b;
    int c, d;
    char s[64];
    //  p = malloc ( MAX * sizeof *p );

    p = (float *) malloc(MAX*sizeof(float));    /* get stack memory */  
    p2 = (int *) malloc(MAX*sizeof(int));       /* get stack memory */
    if (!p || !p2) {
        printf("Allocation Failure\n");
        exit(1);
    }

    tos = p; bos = p + MAX-1;
    tos2 = p2; bos2 = p2 + MAX-1;

    printf("\nRPN Calculator\n");
    printf("Enter 'i' for Integer mode (default)\n");
    printf("Enter 'f' for Floating point mode\n");
    printf("Enter 'm' to Show Menu\n");
    printf("Enter 'q' to Quit\n\n");

    char *endptr;

    do {        
        printf("> ");
        scanf("%s", s);

        if (imode == 0) {       /* Floating Mode */

            float val = strtof(s, &endptr);     /* string to float conversion */
            if (*endptr == '\0') {
                //printf("Got only the floateger: %d\n", val);
            }
            else {  
                //printf("operator: %s\n", endptr); 
                //printf("float: %f\n", val);
                if (val != 0){      /* don't push val on stack if 0 */
                    push(val);
                }
            }

        switch(*endptr) {
            case 'i':
                printf("\n (Integer Mode)\n");
                imode = 1;      /* mode flag */
                break;
            case 'f':
                printf("\n (Floating Point Mode)\n");
                imode = 0;      /* mode flag */
                break;
            case 'm':
                printf("\nRPN Calculator\n");
                printf("Enter 'i' for Integer mode\n");
                printf("Enter 'f' for Floating point mode\n");
                printf("Enter 'm' to Show Menu\n");
                printf("Enter 'q' to Quit\n\n"); 
                break;
            case '+':
                a = pop(); b = pop();
                printf("= %f\n",a+b);
                push(a+b);
                break;
            case '-':
                a = pop(); b = pop(); 
                printf("= %f\n", b-a); 
                push(b-a);
                break;  
            case '*':
                a = pop(); b = pop(); 
                printf("= %f\n", a*b); 
                push(a*b);
                break;
            case '/':
                a = pop(); b = pop();
                if(a == 0){
                    printf("Cannot divide by zero\n");
                    break;
                }
                printf("= %f\n", b/a);
                push(b/a);
                break;
            case '.':
                a = pop(); push(a);
                printf("Top of stack value: %f\n", a);
                break;  
            default:
                push(val);
        }

        }   
        else {          /* Integer Mode */

                int val2 = strtod(s, &endptr);      /* string to float conversion */
                if (*endptr == '\0') {
                    //printf("Got only the floateger: %d\n", val);
                }
                else {  
                //printf("operator: %s\n", endptr); 
                //  printf("int: %d\n", val2);
                    if (val2 != 0){     /* don't push val on stack if 0 */
                        push2(val2);
                    }
                }

            switch(*endptr) {
                case 'i':
                    printf("\n (Integer Mode)\n");
                    imode = 1;      /* mode flag */
                    break;
                case 'f':
                    printf("\n (Floating Point Mode)\n");
                    imode = 0;      /* mode flag */
                    break;
                case 'm':
                    printf("\nRPN Calculator\n");
                    printf("Enter 'i' for Integer mode\n");
                    printf("Enter 'f' for Floating point mode\n");
                    printf("Enter 'm' to Show Menu\n");
                    printf("Enter 'q' to Quit\n\n"); 
                    break;
                case '+':
                    c = pop2(); d = pop2();
                //  printf("%d\n", c);
                //  printf("%d\n", d);
                    printf("= %d\n",c+d);
                    push2(c+d);
                    break;
                case '-':
                    c = pop2(); d = pop2(); 
                    printf("= %d\n", d-c); 
                    push2(d-c);
                    break;  
                case '*':
                    c = pop2(); d = pop2(); 
                    printf("= %d\n", c*d); 
                    push2(c*d);
                    break;
                case '/':
                    c = pop2(); d = pop2();
                    if(c == 0){
                        printf("Cannot divide by zero\n");
                        break;
                    }
                    printf("= %d\n", d/c);
                    push2(d/c);
                    break;
                case '.':
                    c = pop2(); push2(c);
                    printf("Top of stack value: %d\n", c); 
                    break;  
                default:
                    //  push(atoi(s));
                    push2(val2);
            }           
        }       
    } while (*s != 'q');    /* Do until 'q' is entered */
return 0;
}       

void push (float f) {   /* Put an element on the stack */
    *p = f; 
    p++;
}

float pop (void) {  /* Get the element from the top of the stack */
    p--;
    return *p;
}

void push2 (int i) {
    *p2 = i;
    p2++;
}

int pop2(void) {
    p2--;
    return *p2;
}

This is what I have so far for the int mode:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 50

int *p;
int *tos;
int *bos;

void push(int i);
int pop(void);

int main (void)
{
    int a, b;
    char s[5];
    int c;
    int count;

    tos = p;
    bos = p + MAX-1;

    printf("\nRPN Calculator\n");
    printf("Enter 'i' for integer mode\n");
    printf("Enter 'f' for floating point mode\n");
    printf("Enter 'q' to quit\n\n");
    char *endptr;

    do {        
        printf("> ");
        //scanf("%s", s);
        count = 0;
        while ((count < 5) && (c != EOF) && (c !='\n')) {    /* don't go over the array size! */
            s[count] = c;
            ++count;
            c = getchar();     /* get another character */
        }       

        //for (c=0; c<count; c++) {
        //putchar(c);
        //}

        int val = strtol(s, &endptr, 10);

        if (*endptr == '\0') {
            //printf("Got only the integer: %d\n", val);
        }
        else {  
            //printf("operator: %s\n", endptr); 
            //printf("integer: %d\n", val);
            if (val != 0){      /* don't push val on stack if 0 */
                push(val); 
            }
        }

            switch(*endptr) {
         case 'i':
         printf("(Integer Mode)\n");
         break;
         case 'f':
         printf("(Floating Point Mode)\n");
         break;
         case '+':
         a = pop();
         b = pop();
         // printf("%d\n",a);
         // printf("%d\n",b);
         // printf("%d\n",val);
         printf("%d\n", a+b);
         push(a+b);
         break;
         case '-':
         a = pop(); 
         b = pop(); 
        // printf("%d\n", b-a); 
         push(b-a);
         break; 
         case '*':
         a = pop(); 
         b = pop(); 
        // printf("%d\n", a*b); 
         push(a*b);
         break;
         case '/':
         a = pop(); 
         b = pop();
         if(a == 0){
        // printf("Cannot divide by zero\n");
         break;
         }
        // printf("%d\n", b/a);
         push(b/a);
         break;
         case '.':
         a = pop(); push(a);
        // printf("Current value on top of stack: %d\n", a);

         break; 
         default:
         push(val);
         }
    } while (c != 'q'); /* Do until 'q' is entered */

    return 0;
}       

void push (int i)   /* Put an element on the stack */
{
    if (p > bos){
        printf("Stack Full\n");
        return;
    }
    *p = i;
    p++;
}

int pop (void)  /* Get the element from the top of the stack */
{
    p--;
    if(p < 0) {
        printf("Stack Underflow\n");
        return 0;
    }
    return *p;
}
A: 

Whether you can use strtol() or not depends on your embedded system.

The C standard recognizes two environments. One is the normal 'hosted' environment, which provides full support for the C library. The other is a 'freestanding' environment. That only has to provide support for 7 headers in C:

<float.h>
<iso646.h>
<limits.h>
<stdarg.h>
<stdbool.h>
<stddef.h>
<stdint.h>

Since you are in an embedded environment, you can rely on those 7. For everything else, you need to read the manual for your environment.

The chances are good that you can use strtol().

Jonathan Leffler