Wpisywanie tekstu w kalkulatorze

0

Witam. Pytanie następujące: Jak do poniższego kalkulatora dodać możliwość wpisywania liczb za pomocą tekstu? By automatycznie sobie konwertował "dwa" = 2 i obliczał zadanie. Poza tym potrzebuje, by funkcje te były przeciążone. Myśle, że z przeciążeniem sobie jakoś poradze, ale z wpisywaniem tekstu jako liczby już niezbyt.

#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <math.h>

using namespace std;
int dzialanie, powrot;
double Liczba1, Liczba2, Wynik, decyzja, ilosc;
int main()
{
start:
	cout << "Cwiczenie 5 - Przeciazenie funkcji - KALKULATOR \n";
	cout << "Wybierz dzialanie z menu \n" << endl;
	cout << "[1] Dodawanie " << endl;
	cout << "[2] Odejmowanie " << endl;
	cout << "[3] Mnozenie " << endl;
	cout << "[4] Dzielenie " << endl;
	cout << "[5] Pierwiastek N-tego stopnia " << endl;
	cout << "[6] Srednia artmetyczna " << endl;
	cout << "[7] Potegowanie " << endl;
	cout << "[0] Aby zakonczyc dzialanie kalkulatora \n" << endl;
	cout << "Decyzja: ";
	cin >> dzialanie;
	if (dzialanie <= 6 && dzialanie > 0)
	{
		cout << "Podaj pierwsza liczbe: ";
		cin >> Liczba1;
		cout << "Podaj druga liczbe: ";
		cin >> Liczba2;
	}
	cout << "\n";
	switch (dzialanie)
	{
	case 1:
		Wynik = Liczba1 + Liczba2;
		break;
	case 2:
		Wynik = Liczba1 - Liczba2;
		break;
	case 3:
		Wynik = Liczba1 * Liczba2;
		break;
	case 4:
		if (Liczba2 == 0)
		{
			cout << "Nie dzielimy przez zero!\n";
		}
		else
			Wynik = Liczba1 / Liczba2;
		break;
	case 5:
		cout << "Wybrano pierwiastek dowolnego stopnia. \n";
		cout << "Podaj liczbe: ";
		cin >> Liczba1;
		cout << "Podaj stopien pierwiastka: ";
		cin >> Liczba2;
		double power;
		power = exp(log(Liczba1) / Liczba2);
		Wynik = power;
		break;
	case 6:
		cout << "Wybrano srednia artmetyczna. \n";
		Liczba1 = 0;
		Wynik = 0;
		ilosc = 0;
		cout << "Napisz 12345 aby zakonczyc wpisywanie liczb: \n";
	
		{
			cout << "Podaj liczbe: ";
				cin >> Liczba1;
				if (Liczba1 == 12345) break;
				Wynik += Liczba1;
				ilosc += 1;
		}
		Wynik = Wynik / ilosc;
			break;
	case 7:
		cout << "Wybrano potegowanie. \n";
		cout << "Podaj liczbe: ";
		cin >> Liczba1;
		cout << "Podaj potege: ";
		cin >> Liczba2;
		Wynik = pow(Liczba1, Liczba2);
		break;
	case 0:
		cout << "\n\nDziekujemy za skorzystanie z kalkulatora. \nKliknij dowolny klawisz aby kontynuowac\n\n\n";
		return 0;
		break;
	default:
		break;
	}
	if (dzialanie == 0 || dzialanie >= 10)
	{
		cout << "\nWcisnieto nieprawidlowy klawisz" << endl;
		return 0;
	}
	else
		cout << "\nWynik wynosi: " << Wynik << endl;
	cout << "\n [0] Aby zamknac kalkulator";
	cout << "\n [1] Aby korzystac dalej z kalkulatora\n";
	cout << "Decyzja: ";
	cin >> powrot;
	switch (powrot)
	{
	case 1:
		goto start;
		break;
	case 0:
		cout << "\n\nDziekujemy za skorzystanie z kalkulatora. \nKliknij dowolny klawisz aby kontynuowac\n\n\n";
		return 0;
		break;
	default:
		return 0;
		break;
	}
}
1

Twój kod w tym miejscu


    cin >> Liczba1;

podmieniasz na kod


    cin >> Liczba1;
   someNumber = decodeNumber(Liczba1);

i piszesz funkcje


   int decodeNumber(char * number)
   {
   //Jeśli number to liczba to zwroc number
   //Jeśli number to tekst to sprawdz czy tekst jest liczba i zwroc odpowiedni
   }

Od biedy mozesz zrobic switcha ale przy bardziej zlozonych musisz sie nagomnastykowac.

0

Przy wszystkich działaniach muszę

cin >> Liczba1;

dodać te

Liczba1 = decodeNumber(Liczba1);

Czy tylko na samym początku zaraz po menu? Oczywiście do Liczba1 i Liczba2 musze dopisać te decodeNumber, tak?
Jeśli chodzi o pisanie funkcji to właśnie nie wiem co tu może być. Aż tak to się nie znam. To ma być prosty programik.

1

Liczba1 = decodeNumber(Liczba1);

Nie zadziała, bo Liczba1 to string, a nie int, który pewnie będzie zwracany z decodeNumber.
To gdzie użyjesz decodeNumber nie ma takiego znaczenia, możesz tego użyć po wczytaniu obu liczb zakładając, że obie będą poprawne,
lub po próbie wczytania każdej z osobna, gdzie możesz ponawiać wczytanie aż do pojawienia się poprawnej (np. blok try-catch).
W funkcji powinno się pojawić sprawdzenie, czy napis zawiera samego inta funkcją parsującą stringa na inta, również najlepiej w bloku
try-catch, aby nie wywalić programu, gdy string nie okaże się intem, natomiast zrobienie z napisu "dwa" inta najprostsze będzie switch-casem.
Użyj jakiejś funkcji porównującej napisy, i w instrukcji switch-case gdy "dwa" równa się "dwa" zwróć 2.

0

a przy okazji jak zrobić przeciążenie tych funkcji:

int dzialanie, powrot;
double Liczba1, Liczba2, Wynik, decyzja, ilosc;
0
Syene napisał(a):

a przy okazji jak zrobić przeciążenie tych funkcji:

int dzialanie, powrot;
double Liczba1, Liczba2, Wynik, decyzja, ilosc;

To są deklaracje zmiennych,

int dzialanie(typ_parametru1 parametr1, typ_parametru2 parametr2...);

to jest deklaracja funkcji, do której od razu możesz dodać jej definicję zastępując średnik otwierającą klamrą.
Przeciążać możesz np. poprzez zmianę ilości lub typów parametrów zachowując tą samą nazwę, np.

int dzialanie(int liczba1, int liczba2);
int dzialanie(double liczba1, double liczba2);
0

Tylko przeciążenie funkcji nie następuje przy deklaracji zmiennych by program mógł sobie wybrać, według którego typu ma działać?

int powrot;
double Wynik, decyzja, ilosc;
int dzialanie(int Liczba1, int Liczba2);
double dzialanie(double Liczba1, double Liczba2);
0
Syene napisał(a):

Tylko przeciążenie funkcji nie następuje przy deklaracji zmiennych by program mógł sobie wybrać, według którego typu ma działać?

int powrot;
double Wynik, decyzja, ilosc;
int dzialanie(int Liczba1, int Liczba2);
double dzialanie(double Liczba1, double Liczba2);

Nie wiem czy rozumiem dobrze to co napisałeś, ale tak, piszesz powiedzmy kilka wariantów dla różnych typów danych wejściowych i przy wywołaniu, program sam wybiera, której wersji użyć na podstawie parametrów, której podajesz przy wywołaniu.

0

Ale wystarczy, że te przeciążenie zrobie raz czy np. musze je dodawać przed każdym działaniem matematycznym?

0
Syene napisał(a):

Ale wystarczy, że te przeciążenie zrobie raz czy np. musze je dodawać przed każdym działaniem matematycznym?

Chyba nie rozumiem, definicję funkcji dla danych parametrów piszesz raz, potem możesz danej funkcji użyć wielokrotnie.

int dodawanie(int a, int b){return a+b;}
int main()
{ int wyn1 = dodawanie(5,10);
int wyn2 = dodawanie(5,5);
int wyn3 = dodawanie(200,1000);
}

O to Ci chodzi?

0

Jesteś mi w stanie wklepać te przeciążenie do kodu w głównym poście? Bo inaczej się chyba nie zrozumiemy :P

0

Niestety nie, ponieważ tam nie ma żadnej funkcji do przeciążenia. Spróbuj napisać to chociaż strukturalnie :)

0

No to teraz jestem zielony ;o Nie wiem jaką funkcję dodać..

0

Piszesz wszystko w funkcji głównej main, poza funkcją main dodaj inną, np. dodawanie, która potem wywołasz w mainie :)
Polecam poczytać o wspomnianym wcześniej programowaniu strukturalnym.

0

Musisz mieć zawarte w programie reguły przetwarzanie tekstu, tzn. musisz określić co program ma zrobić w zależności od tego jaki tekst sobie przyjmie, zrób sobie tablicę/mapę liczb podstawowych, tablicę/mapę prefiksów i sufiksów i w zależności od tego jakie liczby, prefiksy, sufiksy znajdują się w tekście wejściowym wykonujesz odpowiednie akcje np.
Użytkownik podaje: sto dwadzieścia trzy
z mapy liczby odczytujesz wartość i przypisujesz ją do jakiejś zmiennej,
czytasz dalej dwa czytasz wartość i do zmiennej,
dzieścia czyli poprzednia liczba *10 + pierwsza odczytana wartość,
trzy odczytujesz wartość i suma z poprzednią.
Może trochę zawile ale nie widzę w tym innego rozwiązania, a pamiętam że coś takiego kiedyś robiłem z powodzeniem a tej zasadzie ale nie mogę znaleźć tego kodu.

0
januszoo napisał(a):

Piszesz wszystko w funkcji głównej main, poza funkcją main dodaj inną, np. dodawanie, która potem wywołasz w mainie :)
Polecam poczytać o wspomnianym wcześniej programowaniu strukturalnym.

int suma(int Liczba1, int Liczba2)
{
	return Liczba1 + Liczba2;
}
double suma(double Liczba1, double Liczba2) 
{
	return Liczba1 + Liczba2;
}

a potem wywołanie w mainie:

case 1:
		cout << "Wynik dodawania wynosi " << suma(Liczba1, Liczba2) << endl;
		break;

Dobrze zrozumiałem?

0

Tylko teraz czy musze do kazdego kolejnego dzialania z osobna (mnozenie, dzielenie, odejmowanie itd) pisac tak samo te przeciazenie? czy idzie ten kod jakos zawęzić?

0

Funkcje musisz mieć osobne do dodawania, odejmowanie, dzielenia, mnożenia. Co najwyżej żeby nie pisać ich przeciążonych możesz skorzystać z szablonów, ale raczej masz poćwiczyć przeciążanie funkcji, a nie poznawać szablony.

0

To w chwili obecnej nie jest zbyt krótki ten kodzik:

#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <math.h>

using namespace std;


int suma(int Liczba1, int Liczba2)
{
	return Liczba1 + Liczba2;
}
double suma(double Liczba1, double Liczba2) 
{
	return Liczba1 + Liczba2;
}
float suma(float Liczba1, float Liczba2)
{
	return Liczba1 + Liczba2;
}

int roznica(int Liczba1, int Liczba2)
{
	return Liczba1 - Liczba2;
}
double roznica(double Liczba1, double Liczba2)
{
	return Liczba1 - Liczba2;
}
float roznica(float Liczba1, float Liczba2)
{
	return Liczba1 - Liczba2;
}

int iloczyn(int Liczba1, int Liczba2)
{
	return Liczba1 * Liczba2;
}
double iloczyn(double Liczba1, double Liczba2)
{
	return Liczba1 * Liczba2;
}
float iloczyn(float Liczba1, float Liczba2)
{
	return Liczba1 * Liczba2;
}


int iloraz(int Liczba1, int Liczba2)
{
	return Liczba1 / Liczba2;
}
double iloraz(double Liczba1, double Liczba2)
{
	return Liczba1 / Liczba2;
}
float iloraz(float Liczba1, float Liczba2)
{
	return Liczba1 / Liczba2;
}

int main()
{
	int dzialanie, powrot;
	double Liczba1, Liczba2, Wynik, ilosc;
start:
	cout << "Cwiczenie 5 - Przeciazenie funkcji - KALKULATOR \n";
	cout << "Wybierz dzialanie z menu \n" << endl;
	cout << "[1] Dodawanie " << endl;
	cout << "[2] Odejmowanie " << endl;
	cout << "[3] Mnozenie " << endl;
	cout << "[4] Dzielenie " << endl;
	cout << "[5] Pierwiastek N-tego stopnia " << endl;
	cout << "[6] Srednia artmetyczna " << endl;
	cout << "[7] Potegowanie \n" << endl;
	cout << "[0] Aby zakonczyc dzialanie kalkulatora \n" << endl;
	cout << "Decyzja: ";
	cin >> dzialanie;
	if (dzialanie <= 4 && dzialanie > 0)
	{
		cout << "Wpisz pierwsza liczbe: ";
		cin >> Liczba1;


		cout << "Wpisz druga liczbe: ";
		cin >> Liczba2;

	}

	cout << "\n";
	switch (dzialanie)
	{
	case 1:
		cout << "Wynik dodawania wynosi " << suma(Liczba1, Liczba2) << endl;
		break;
	case 2:
		cout << "Wynik odejmowania wynosi " << roznica(Liczba1, Liczba2) << endl;
		break;
	case 3:
		cout << "Wynik mnozenia wynosi " << iloczyn(Liczba1, Liczba2) << endl;
		break;
	case 4:
		if (Liczba2 == 0)
		{
			cout << "Nie dzielimy przez zero!\n";
		}
		else
			cout << "Wynik dzielenia wynosi " << iloraz(Liczba1, Liczba2) << endl;
		break;
	case 5:
		cout << "Wybrano pierwiastek dowolnego stopnia. \n";
		cout << "Podaj liczbe: ";
		cin >> Liczba1;
		cout << "Podaj stopien pierwiastka: ";
		cin >> Liczba2;
		double power;
		power = exp(log(Liczba1) / Liczba2);
		Wynik = power;
		break;
	case 6:
		cout << "Wybrano srednia artmetyczna. \n";
		Liczba1 = 0;
		Wynik = 0;
		ilosc = 0;
		cout << "Napisz 12345 aby zakonczyc wpisywanie liczb: \n";

		{
			cout << "Podaj liczbe: ";
			cin >> Liczba1;
			if (Liczba1 == 12345) break;
			Wynik += Liczba1;
			ilosc += 1;
		}
		Wynik = Wynik / ilosc;
		break;
	case 7:
		cout << "Wybrano potegowanie. \n";
		cout << "Podaj liczbe: ";
		cin >> Liczba1;
		cout << "Podaj potege: ";
		cin >> Liczba2;
		break;
	case 0:
		cout << "\n\n Dziekuje za skorzystanie z kalkulatora. \n ";
		system("pause");
		return 0;
		break;
	default:
		break;
	}
	if (dzialanie == 0 || dzialanie >=8)
	{
		cout << "\n Wcisnieto nieprawidlowy klawisz" << endl;
		return 0;
	}
	else
	cout << "\n [0] Aby zamknac kalkulator.";
	cout << "\n [1] Aby korzystac dalej. \n";
	cout << "Decyzja: ";
	cin >> powrot;
	switch (powrot)
	{
	case 1:
		goto start;
		break;
	case 0:
		cout << "\n\n Dziekuje za skorzystanie z kalkulatora. \n";
		system("pause");
		return 0;
		break;
	default:
		system("pause");
		return 0;
		break;
	}
}

A gdzie tu jeszcze dodać tą funkcje wpisywania tekstu ;o
I faktycznie, troche zawile to opisałeś wcześniej. Polecono mi by ogarnąć parser matematyczny, ale to wyższa jazdy szkoła dla mnie.

0

No tam gdzie masz te deklaracje funkcji powinna być ta konwertująca słowa na liczby, zamiast tych słów lepiej zrób sobie kalkulator z ONP, podajesz mu wyrażenie np, 1+23(2-1) on sobie tworzy ONP z tego i oblicza, przyjemne w działaniu, łatwe do napisania.

0

A propozycja z jednego postu w tym temacie nie będzie prostsza?

 int decodeNumber(char * number)
   {
   //Jeśli number to liczba to zwroc number
   //Jeśli number to tekst to sprawdz czy tekst jest liczba i zwroc odpowiedni
   }

Próbowałem zajrzeć w te ONP i parsery matematyczne i to jest aż za dużo jak na moją głowę.

0

Jeśli zakładasz ze wprowadzać będziesz jedynie słowa które będziesz miał zapisane w programie to nie będzie trudne, ale do ilu napiszesz taką relację:
"zero" - 0
"jeden" - 1
"dwa" - 2
dziesięciu, dwudziestu liczb?

0

To jest caly czas forma nauki takze watpie by tutaj chodzilo o wielkie liczby, a bardziej o zaznajomienie sie z kodem. Mam wszystkie chwyty dozwolone, nie mniej jednak w necie nie ma kodow, ktore moglbym wklepac jako zamiane cyfr jako tekstu i na odwrót, dlatego męczę Was tutaj ;x

{
		std::map < string, int > mapa{ { "1", 1 },{ "jeden", 1 },{ "2", 2 },{ "dwa", 2 } };
		string Liczba1, Liczba2;
		cin >> Liczba1 >> Liczba2;
		cout << mapa[Liczba1] + mapa[Liczba2];
	}

W tym kierunku iść?

0

Możesz iść w tym kierunku.

2

Dla zainspirowania...

#include <unordered_map>
#include <string>
#include <sstream>
#include <iostream>

unsigned valueToName(const std::string& valueStr) {
    std::unordered_map<std::string, unsigned> strToValue = {
        {"zero", 0}, {"jeden", 1}, {"dwa", 2}, {"trzy", 3}, {"cztery", 4}, {"pięć", 5},
        {"sześć", 6}, {"siedem", 7}, {"osiem", 8}, {"dziewięć", 9}, {"dziesięć", 10},
        {"jedenaście", 11}, {"dwanaście", 12}, {"trzynaście", 13}, {"czternaście", 14},
        {"piętnaście", 15}, {"szesnaście", 16}, {"siedemnaście", 17}, {"osiemnaście", 18},
        {"dziewiętnaście", 19}, {"dwadzieścia", 20}, {"trzydzieści", 30},
        {"czterdzieści", 40}, {"pięćdziesiąt", 50}, {"sześćdziesiąt", 60}, 
        {"siedemdziesiąt", 70}, {"osiemdziesiąt", 80}, {"dziewięćdziesiąt", 90}
    };
    unsigned result = 0;
    std::stringstream ss;
    ss << valueStr;
    std::string token;
    while(ss >> token) {
        result += strToValue[token];
    }
    return result;
}

int main() {
    std::string valueName;
    std::cout << "Podaj słownie liczbę z zakresu [0, 99]: ";
    std::getline(std::cin, valueName);

    unsigned value = valueToName(valueName);
    std::cout << "Liczbowo to: " << value << '\n';
}

Do 1000 pójdzie łatwo, później będziesz miał trochę if'ów :-)

0

Pomaga, aczkolwiek nie jestem na takim poziomie by inspirowało xd Nawet nie wiem gdzie tu wpisac zmienne by po wpisaniu tekstu pokazalo liczbe i zaczeło liczyć..

Nie wystarczy bym po przetworzeniu tekstu na liczbe wczytał ją jako moją pierwszą zmienną? cin >> Liczba1; i tak samo w przypadku drugiej zmiennej, jeszcze raz kod na wpisanie słownie, przetworzenie i wczytanie cin >> Liczba2; ?
Problem pojawia się przy 'value' ponieważ jest podwójnie inicjalizowany, a nie moge go zmienić bo jest to wywołanie..

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