Search code examples
cfgetsscanf

Read expression using fgets and get the numeric values using sscanf


I have to do a program which reads an RPN (Reverse Polish Notation) expression and then evaluates it.

For reading the expression I have to use fgets. And then for get the numeric values of this expression I have to use sscanf. Input and output will be done using STDIN and STDOUT.

The idea is to read something like that:

5 2 pi cos - 4 * + 3 -

And then save this expression into m x 2 matrix.

I can read a number (float or not), a constant (like pi), an operator (like + or - or /) or a function (like sin or cos).

While I'm readind every character of the expression I have to store this information into the matrix, and if I have a number i will set it at the position matrix[0][k], where k is not important, if I have constant it will go at the position matrix[1][k], k is not important, operator in matrix[2][k], k is not important and function in matrix[3][k].

So the before expression will be like this:

{{0,5},{0,2},{1,0},{3,2},{2,1},{0,4},{2,2},{2,0},{0,3},{2,1}}.

I have to do this in C, and I am facing some problems. The main problem is to get the values of the expression entered by user. I have this:

int main() {

// Cadena de caracteres donde guardamos la expresion rpn
char str[MAX];

int matrix[MAX][2];
int i = 0; 

printf("Enter a string: ");
// Cogemos los 100 caracteres que haya por consola, controlando errores
if(fgets(str, 100, stdin) == NULL) printf("Error leyendo por consola");

/* Si hay un salto de linea lo borramos */
i = strlen(str)-1;
if( str[ i ] == '\n') str[i] = '\0';

converteix_codis(matrix, str, i);

// Creamos la pila
pila p;
// Inicializamos la pila
initStack(&p);

int a = avalua_rpn(matrix, &p);

// Comprobar si se ha podido evaluar el rpn o no
printf("avalua = %d\n", a);

printf("This is your string: %s\n", str);

return 0;   
}


void converteix_codis(int matriu[MAX][2], char str[MAX], int i)
{
    int tamanyo = 0;

int j, k = 0;
int nombres = 0, constants = 0, operacions = 0, funcions = 0; 
char a[3] = "";
for(j = 0; j < i; ++j) {
    // Si el caracter que leemos es un digito
    if(isdigit(str[j])) {
        matriu[0][nombres] = (int) str[j];
        ++nombres;
        ++tamanyo;
    }
    // Si el caracter que leemos es una operacion
    else if(ispunct(str[j])) {
        int num;
        if(str[j] == '+') num = 0;
        else if(str[j] == '-') num = 1;
        else if(str[j] == '*') num = 2;
        else if(str[j] == '/') num = 3;
        else if(str[j] == '^') num = 4;
        matriu[2][operacions] = num;
        ++operacions;
        ++tamanyo;
    }

}
}

In the function converteix_codis I am trying to store this information, but I don't know how to get the strings sin, cos, pi, e and others for storing them into the matrix. With operations and digits I tried that, but if I have a float it won't read it ok. Any suggestions about how to use fgets and sscanf to read this? (I have to use them because is a requeriment).

Thank you a lot!


Solution

  • Examples of splits and numerical decision(Easy way, not rigorous way).

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <stdbool.h>
    
    bool isNumber(const char *str, double *num){
        char *endp;
        double n = strtod(str, &endp);
        if(*endp == '\0'){
            *num = n;
            return true;
        }
        *num = NAN;
        return false;
    }
    
    int main(void){
        char str[] = "5 2 pi cos - 4 * + 3 -";
        char *token;
        double n;
    
        token = strtok(str, " \t\n");
        while(token){
            if(isNumber(token, &n)){//if(1==sscanf(token, "%lf%c", &n, &ch)){//char ch;
                printf("%g\n", n);
            } else {
                printf("%s\n", token);
            }
            token = strtok(NULL, " \t\n");
        }
        return 0;
    }