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;
}