Kalkulator onp, problem z obliczeniem wyrażenia

0

Cześć wszystkim, mam do zrobienia projekt na zaliczenie w ANSI/C, jednak mam problem z obliczeniem wyrażenia, które podaje użytkownik. Jak dotąd udało mi się zrobić implementację stosu, walidację poprawności wprowadzonych znaków i na tą chwilę to większość. Nie wiem jak poprawic funkcję licz_ONP, tak aby zwracało poprawny wynik wpisany przez użytkownika postaci onp, np. 2 2 + żeby zwróciło 4, itp. Za wszelkie porady dziękuję. Pozdrawiam

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


struct stack
{
double data;
struct stack * next;
};

///poczatek implementacji funkcji do obslugi stosu
double push(struct stack **top,double number)
{
    if(*top==NULL)
    {
        *top=(struct stack *)malloc(sizeof(struct stack));
        (*top)->data=number;
        (*top)->next=NULL;
    }
    else
    {
        struct stack * new_element;
        new_element=(struct stack *)malloc(sizeof(struct stack));
        new_element->data=number;
        new_element->next=*top;
        *top=new_element;
    }
}

double pop(struct stack **top)
{
    if (*top==NULL) {
      printf("Stos jest pusty. Nie ma co zdjac ze stosu");
	}else {
	 struct stack * tmp=NULL;
   	 tmp=(*top)->next;
   	 free(*top);
   	 *top=tmp;
	}
}

double peek(struct stack *top)
{
    if(top==NULL) printf("stos jest pusty");
    else {
        struct stack *current=top;
        do {
            printf("%lf", current->data);
            printf("\n");
            current = current->next;
         }while (current != NULL);

}
}
///koniec implementacji funkcji stosu.


//Funkcja odpowiedzialna za obliczenie wyrazenia podanego przez uzytkownika w postaci onp.

double licz_ONP(char *wyr)
{

double  first_argument=0, second_argument=0, result=0;
struct stack *top=NULL;
        switch(*wyr)
        {
        case '+':
            result = pop(&top) + pop(&top);
            push(&top,result);
            break;
        case '-':
            first_argument = pop(&top);
            second_argument = pop(&top);
            push(&top,second_argument - first_argument);
            break;
        case '*':
            result = pop(&top) * pop(&top);
            push(&top,result);
            break;
        case '/':
            first_argument = pop(&top);
            second_argument = pop(&top);
            push(&top,second_argument / first_argument);
            break;
        case '^':
            first_argument = pop(&top);
            second_argument = pop(&top);
            result = pow(second_argument,first_argument);
            push(&top,result);
            break;
        case '\0':
            pop(&top);
        }

        wyr++;

}

char podaj_znaki_onp(char * wyr)
{
    //  Funkcja sprawdza znaki podane przez użytkownika.
    // Liczby są zapisywane w postaci dziesietnej z tablicy kodów ASCII.
    // Odczytujac kody, mozna wywnioskowac, ze dopuszczone sa jedynie liczby w postaci dziesietnej kodu ascii od 32 do 58.
    //  Jednakże są pewne wykluczenia, np. wprowadzenie znaku '&' zapisanego w postaci dec 38 spowoduje blad, ktory program rozpozna.
    gets(wyr);
for(int i=0; i<strlen(wyr);i++)
	{
  if((wyr[i] <31) || (wyr[i] > 58) || wyr[i]==33 || wyr[i]==34|| wyr[i]==35 || wyr[i]==36
     || wyr[i]==38 || wyr[i]==39 || wyr[i]==40 || wyr[i]==41 || wyr[i]==44 )
  {
    puts("Uzytkowiniku wprowadziles zly znak");
    break;
  }
  else
  {

  }
    }
}
char podaj_znaki_kalkulatora(char * wyr)
{
    gets(wyr);
for(int i=0; i<strlen(wyr);i++)
	{
  if((wyr[i] <31) || (wyr[i] > 58) || wyr[i]==33 || wyr[i]==34|| wyr[i]==35 || wyr[i]==36
     || wyr[i]==38 || wyr[i]==39  || wyr[i]==44 )
  {
    puts("Uzytkowiniku wprowadziles zly znak");
    break;
  }
  else
  {

  }
    }
}

int main()
{
char  wyr[50];
char wybor[0];
puts("wprowadz znak wyboru");
puts("po wprowadzeniu liczny 1 wybierz kalkulator onp");
puts("po wprowadzeniu liczny 2 wybierz kalkulator normalny");
gets(wybor);


int wybierz=atoi(&wybor);
    printf("%d\n",wybierz);
    system("cls");

if(wybierz==1)
{
    puts("wprowadz wyrazenie onp:");
    podaj_znaki_onp(wyr);

    printf("%s",wyr);
    printf("%d",licz_ONP(wyr));


}
else if (wybierz==2)
{
    puts("wprowadz wyrazenie arytmetyczne");
    podaj_znaki_kalkulatora(wyr);
    printf("%s",wyr);
}
else puts("koniec programu");
return 0;
}
1
  1. po co ci ten if w double push(struct stack **top,double number). Cześć w else załatwia oba przypadki.
  2. Gdzie jest return w double pop(struct stack **top)? To jest główny błąd. Kompilator na pewno ostrzega cię o tym błędzie. Używaj -Wall i -Werror by unikać takich baboli.
  3. Co niby ma robić double peek(struct stack *top)? Bo nie robi tego czego bym się spodziewał po stosie.
  4. a gdzie jest pętla iterująca po napisie? Powinna być w licz_ONP lub powinna wywoływać licz_ONP

Na tym przestałem czytanie.

I jeszcze jedno: naucz się używać debuggera, tak szybko jak to możliwe.
Prawda jest taka, że wraz ze wzrostem umiejętności częstotliwość używania tego narzędzia spada.
Jak ktoś jeszcze nie ma umiejętności programowania, powinien używać debugera w zasadzie bez przerwy (jako doskonałe narzędzie do nauki).

1

Mi się nie chce analizować całości, ale od razu widać że ta funkcja licz_ONP bierze tylko pierwszy element ze stosu(nie nikam czy stos jest poprawnie zrobiony), ponieważ wg założeń pierwszym elementem stosu jest liczba a nie znak no to mija ci wszystkie case`y w tym switchu i nie robi nic. Napisz sobie deafulta na końcu i zrób jakiegoś printfa, wtedy zobaczysz.

0

Możesz podrzucić link? Nie patrzyłem się na inne i sam zdziwiony tym jestem

1 użytkowników online, w tym zalogowanych: 0, gości: 1