Visualizzazione dei risultati da 1 a 8 su 8

Discussione: [C] Calcolatrice RPN

  1. #1

    [C] Calcolatrice RPN

    Salve a tutti! stavo cercando di implementare una calcolatrice calcolatrice RPN basata su stack per un progetto scolastico, ma sono un po' bloccato. sono molto alle prime armi in c come potete vedere dal codice. Questo è quanto ho scritto:
    codice:
    int parsifica(char * stringa,float * risultato){
        
        if(stringa!=NULL){
            char * s;
            char * buffer=malloc(STRLEN*sizeof(char));
            float (*puntfunz) (float a,float b);
            dd_stack * stack=new_stack();
            if(DEBUG)printf("stack creato e var inizializzate\n");
            for(stringa;*stringa!='\n'||*stringa!='\0';stringa++){
                if(DEBUG)printf("trovato %c\n",*stringa);
                s=stringa;
                if(*stringa=='+'||*stringa=='-'||*stringa=='*'||*stringa=='/'){
                    if(DEBUG)printf("trovato operatore: %c\n",*stringa);
                    switch (*stringa){
                        case '+':
                            puntfunz = somma;
                            break;
                        case '-':
                            puntfunz = sottrai;
                            break;
                        case '*':
                            puntfunz = moltiplica;
                            break;
                        case '/':
                            puntfunz = dividi;
                            break;
                    }
                    push(stack,puntfunz(pop(stack),pop(stack)));
                }
                if(*stringa == ' '){
                    if(DEBUG)printf("trovato 1 spazio numero in buffer %s\n",buffer);
                    push(stack,(float)atof(buffer));
                    if(DEBUG)printf("effettuata push di %f\n",(float)atof(buffer));
                    free(buffer);
                    buffer=malloc(STRLEN*sizeof(char));
                }
                else{
                    if(DEBUG)printf("inserisco in buffer\n");
                    *buffer=*stringa;
                    if(DEBUG)printf("inserito in buffer\n");
                    buffer++;
                    if(DEBUG)printf("puntatore a buffer aumentato\n");
                }
            }
            *risultato=pop(stack);
            return 0;
        }
        else{
            fprintf(stderr,"errore nella stringa di input\n");
            return 1;
        }
    }
    Per eseguirla faccio così:
    codice:
    int main(int argc, char *argv[])
    {
    
        float * a;
        parsifica("1 2 + 3 * \n",a);
        printf("%f\n");
        system("pause");
    
    
    }
    il problema è che va in esecuzione, non prende gli input e crasha.
    Per chi fosse così gentile da voler vedere tutto il codice lo trovate qui.
    mi dareste una mano a venirne a capo che sono prossimo alla follia? vi ringrazio sentitamente.

  2. #2

    help

    Ragazzi, nessuno sa darmi una mano? sono proprio bloccato!

  3. #3
    La prima cosa che salta all'occhio è che utilizzi la variabile float* a senza avere effettivamente riservato uno spazio di memoria.
    Dovresti quindi dichiarare

    codice:
    float a;
    e passare alla funzione parsifica il suo puntatore

    codice:
    parsifica("1 2 + 3 * \n",&a);
    Questa soluzione non è comunque la più elegante!

    Inoltre non passi nessun parametro alla funzione printf, che dovrebbe essere

    codice:
    printf("%f\n", a);
    Do un'occhiata al resto e ti faccio sapere

    EDIT:

    nella funzione pop hai dimenticato
    codice:
    p = stack -> top;
    e nel complesso, la gestione dei puntatori non è il massimo.

  4. #4
    Sono riuscito a farlo funzionare.
    Ti posto il codice che ho cercato di modificare il meno possibile per permetterti di comprendere meglio il codice.
    In realtà sarebbe opportuno riscrirverlo.

    codice:
    int parsifica(char * stringa,float * risultato){
        
        if(stringa!=NULL){
            //char * s;
            char * buffer=(char*) malloc(STRLEN*sizeof(char));
    		int y = 0;
            float (*puntfunz) (float a,float b);
    		int i = 0;
    
            dd_stack * stack=new_stack();
            if(DEBUG)printf("stack creato e var inizializzate\n");
    		while (i < (int) strlen(stringa) && stringa[i] != '\n' && stringa[i] != '\0')
    		{
                if(DEBUG)printf("Carattere >> %c\n",stringa[i]);
                //s=stringa;
                if(stringa[i]=='+'||stringa[i]=='-'||stringa[i]=='*'||stringa[i]=='/')
    			{
                    if(DEBUG)printf("Operatore >> %c\n",stringa[i]);
                    switch (stringa[i]){
                        case '+':
                            puntfunz = somma;
                            break;
                        case '-':
                            puntfunz = sottrai;
                            break;
                        case '*':
                            puntfunz = moltiplica;
                            break;
                        case '/':
                            puntfunz = dividi;
                            break;
                    }
                    push(stack,puntfunz(pop(stack),pop(stack)));
                }
                else if(stringa[i] == ' ' && y != 0){
                    printf("SPACE\n");
                    if(DEBUG)printf("trovato 1 spazio numero in buffer %s\n",buffer);
                    push(stack,(float)atof(buffer));
                    if(DEBUG)printf("effettuata push di %f\n",(float)atof(buffer));
                    free(buffer);
                    buffer=(char*) malloc(STRLEN*sizeof(char));
                    y=0;
                    buffer[y] = '\0';
                }
                else{
                    if(DEBUG)printf("inserisco in buffer\n");
                    buffer[y]=stringa[i];
    				buffer[y+1]='\0';
                    if(DEBUG)printf("inserito in buffer\n");
                    y++;
                    if(DEBUG)printf("puntatore a buffer aumentato\n");
                }
    			i ++;
            }
            *risultato=pop(stack);
            return 0;
        }
        else{
            fprintf(stderr,"errore nella stringa di input\n");
            return 1;
        }
    }

  5. #5
    google01, ti ringrazio moltissimo, soprattutto per non aver modificato troppo il codice permettendomi di capire gli errori(anche se errori è un eufemismo nel mio caso).
    Grazie mille, ora vedo di completare il tutto con lettura e scrittura files e altre cose come da specifiche del progetto, poi posto il codice nel caso serva a qualcuno.
    Ti ringrazio ancora moltissimo, davvero.

  6. #6
    Figurati, piacere mio

  7. #7
    google01 , posso chiederti ancora una cosa? Ho implementato la lettura e scrittura su files, in pratica legge le espressioni da un file e ne produce uno di output con le espressioni lette e i risultati. Dopo svariate prove pare che quando faccio l'ultima pop dallo stack, quella per prelevare il risultato, il programma si blocchi. Eppure, dandogli in pasto la stessa equazione non letta da file, il tutto funziona. mi spiegheresti gentilmente il perchè? mi sto scervellando..
    il codice è qua .
    Grazie mille!!!

  8. #8
    facendo riferimento ai sorgenti di ieri, osservando il file infile.txt, ho notato che l'ultima espressione non funziona perchè operatori ed operandi sono separati da due blank anzichè da uno solo, l'errore è senz'altro quello.

    Un altro errore è il controllo sul valore di ritorno della funzione parsifica.
    Se quando il calcolo va a buon fine viene ritornato 0, messo in && con 1, il risultato sarà sempre 0 e quindi il risultato non verrà stampato.
    Io utilizzerei direttamente il valore di ritorno della funzione originale, è fatto apposta

    Purtroppo il codice che hai linkato non posso scaricarlo e quindi ti posto quello di ieri modificato:

    codice:
    int scansiona_file(FILE * infile,FILE * outfile){
        int val=1;
        float risultato;
        time_t t      = time (NULL);
        struct tm *tp = localtime (&t);
        char *stringa = malloc(STRLEN*sizeof(char));
        char *ora = malloc(STRLEN*sizeof(char));
        memset(stringa, '\0', STRLEN);
        memset(ora, '\0', STRLEN);
    //	strftime (ora, STRLEN, "%a %b %e %H:%M:%T %Y", tp);
    //    fprintf(outfile,"Sessione di calcolo del %s",ora);
        while(!feof(infile)){
            fgets(stringa,STRLEN,infile);
            printf("%s\n", stringa);
            fprintf(outfile,"%s\n",stringa);
            if (parsifica(stringa, &risultato) != 0)
            {
                fprintf(outfile,"errore nel calcolo del risultato.\n");
                printf("errore nel calcolo del risultato.\n");
                return 1;
            }
            fprintf(outfile,"Risultato: %f \n\n",risultato);
        }
        return 0;
    }

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.