Napisalem nastepujacy kalkulator w c++:
#include <iostream>
namespace symbole {
enum symbol {liczba, plus, minus, mnozenie, dzielenie, lnaw, pnaw, koniec};
}
void pob_znak();
void liczba_naturalna();
void wyrazenie (int &wyr);
void blad(int b);
char ch = ' '; // ostatni przeczytany znak
int lz = 0; // licznik znaków
char *wyr; // lancuch znaków z wyrazeniem
symbole::symbol sym; // ostatni przeczytany symbol
int wart_liczby; // wartosc ostatniej przeczytanej liczby
int wart_wyrazenia; // wartosc wyrazenia
// Funkcje zwiazane z analiza leksykalna
// Zamiana znaku na symbol
symbole::symbol zamien(char ch)
{
switch (ch)
{
case '+' : return symbole::plus ;
case '-' : return symbole::minus;
case '*' : return symbole::mnozenie;
case '/' : return symbole::dzielenie;
case '(' : return symbole::lnaw;
case ')' : return symbole::pnaw;
case NULL: return symbole::koniec;
}
}
void pob_symbol()
{
// pomin wszystkie spacje
while (ch != '\n' && isspace(ch)) pob_znak();
if (isdigit(ch))
liczba_naturalna();
else
{
sym = zamien(ch);
pob_znak();
}
}
// skladnik, a funkcja skladnik – funkcje wyrazenie
void skladnik (int &cz)
{
switch (sym)
{
case symbole::liczba: cz = wart_liczby; pob_symbol(); break;
case symbole::lnaw: pob_symbol();
wyrazenie(cz);
if (sym == symbole::pnaw)
pob_symbol();
else
blad(3);
break;
default: blad(2);
}
}
void wyrazenie (int &wyr)
{
int skl1, skl2;
symbole::symbol oper;
skladnik(skl1);
while (sym == symbole::plus || sym == symbole::minus || sym == symbole::mnozenie || sym == symbole::dzielenie)
{
oper = sym;
pob_symbol();
skladnik(skl2);
switch (oper)
{
case symbole::plus : skl1 = skl1 + skl2; break;
case symbole::minus: skl1 = skl1 - skl2; break;
case symbole::mnozenie: skl1 = skl1 * skl2; break;
case symbole::dzielenie: skl1 = skl1 / skl2; break;
}
}
wyr = skl1;
}
using namespace std ;
// Umieszcza nastepny znak w ch, zwieksza lz
void pob_znak()
{
ch = wyr[lz++];
}
// Oblicza wartosc liczby naturalnej
void liczba_naturalna()
{
sym = symbole::liczba;
wart_liczby = int(ch) - int('0');
pob_znak();
while (isdigit(ch))
{
wart_liczby = wart_liczby * 10 + int(ch) - int('0');
pob_znak();
};
}
// Funkcje zwiazane z analiza skladni
void blad(int b)
{
cout << wyr << endl;
switch (b)
{
case 1: cout.width(lz); cout << "^"
<< "nieoczekiwany koniec wyrazenia" << endl; break;
case 2: cout.width(lz-1); cout << "^"
<< "oczekiwana cyfra lub \(" << endl; break;
case 3: cout.width(lz-1); cout << "^"
<< "oczekiwany \")\""<< endl; break;
case 4: cout.width(lz-1); cout << "^"
<< "oczekiwany operator lub koniec wyrazenia" <<endl;
};
exit(0);
}
int main()
{
cout << "Wprowadz wyrazenie:" << endl;
//char w[] = "(2 + 8) - (2 + 3)";
char w[20];
cin >> w;
wyr = new char(strlen(w)+1);
strcpy(wyr,w);
pob_symbol();
if (sym == symbole::koniec) blad(1);
wyrazenie(wart_wyrazenia);
if (sym != symbole::koniec)
blad(4);
else
cout << "Wynik:" << endl;
cout << wyr << " = " << wart_wyrazenia << endl;
delete [] wyr;
system("Pause");
return 0;
}
Niby wszystko ladnie dziala jak wpisze np (2+4)2 czyli 12. Natomiast jak napisze 2+42 otrzymam wynik rowniez 12, a nie jak byc powinno 10. Ma ktos moze jakis pomysl jak latwo zmienic/poprawic zeby program dzialal bez wiekszej zabawy i grzebania w kodzie?