Oto jestem - Twoja pierwsza pomoc
. Dopiero się uczysz, więc możesz nie rozumieć czegoś, co napisałem poniżej - pytaj jak najszybciej, to świetny program do nauczenia się czegoś nowego.
Kilka dobrych rad:
- musisz korzystać z dynamicznie alokowanych tablic? Jeśli nie, użyj kontenerów z biblioteki standardowej - przerobiłem Twój program tak, by używał dwóch obiektów typu std::map (pol.-ang., ang.-pol.), ale pod względem pamięci lepiej będzie używać jednej albo std::vector<std::pair<std::string,std::string> > > (wtedy będziemy przeszukiwać ten wektor tak jak to teraz robisz z tablicami)
Kod: Zaznacz cały
using Slownik = std::map<std::string, std::string>;
tworzy alias dla typu std::map<std::string, std::string>
- nie pisz using namespace std;, to bardzo zły zwyczaj, gdyż wprowadza do programu zmienne z przestrzeni nazw biblioteki standardowej
- nie pisz dwóch instrukcji w jednej linii, oddzielając je średnikiem
- nie deklaruj dwóch zmiennych w jednej linii - unikniesz dzięki temu problemów ze znalezieniem błędów w kodzie
- deklaruj zmienne zaraz przed ich użyciem, nie na początku funkcji, łatwiej jest wtedy zrozumieć kod, a kompilator i tak świetnie sobie z tym radzi
Niżej poprawiona wersja, z wyświetlaniem słów na daną literę, poprawianiem literówek i dopisywaniem słów do słownika w programie. Sortownie słów można zrobić, przepisując klucze słownika do np. kontenera
std::vector i wywołując funkcję
std::sort z biblioteki standardowej (nagłówek
<algorithm>). Jeśli chcesz, mogę to zapisać w inny sposób (np.
lambdy jako zwykłe funkcje) albo zamiast
std::map zapisać to za pomocą
std::vector, ale naprawdę dobrze byłoby, gdybyś spróbował wszystko najpierw zrozumieć. Komentarze powinny rozwiać wątpliwości
.
Kilka rzeczy, którymi możesz się zająć:
- przerobić to na klasę SlownikPolAng i z tych wszystkich funkcji zrobić jej metody
- przerobić to z map na vectory
- dodać strukturę na przechowywanie słow - dzięki temu pozbędziemy się potrzeby przechowywania map oraz będziemy mogli przechowywać informację o typie słowa i wzbogacić filtrowanie o wybieranie przymiotników, czasowników i rzeczowników
- poprawić obsługę błędów
Kod: Zaznacz cały
#include <fstream>
#include <iostream>
#include <string>
#include <map>
#include <utility>
// deklarujemy aliasy typow, ktorych uzywamy w calym programie
using Slownik = std::map<std::string, std::string>;
using ParaSlownikow = std::pair<Slownik, Slownik>;
// plik, z ktorego odczytujemy i do ktorego zapisujemy slowa
const std::string PLIK_SLOWNIK = "slowa.txt";
void dodaj_slowo_do_slownika(std::string polskie, std::string angielskie, ParaSlownikow& para)
{
// zapisujemy slowo w obu slownikach:
// polsko-angielskim
para.first[polskie] = angielskie;
// i angielsko-polskim
para.second[angielskie] = polskie;
}
void zapisz_caly_slownik_do_pliku(Slownik& slownik, const std::string& nazwa_pliku)
{
std::fstream od(nazwa_pliku, std::ios::out);
// zapisujemy liczbe slow w slowniku do pliku
od << slownik.size() << '\n';
// zapisujemy slowa, nizej sprawdzanie bledow
for (const auto& slowo : slownik) {
od << slowo.first << " " << slowo.second << '\n';
}
if (!od) {
std::cout << "Nie udalo sie zapisac slow do pliku" << std::endl;
exit(1);
} else {
std::cout << "Zapisano slownik do pliku" << std::endl;
}
}
void dopisz_slowo_do_pliku(const std::string& PL,
const std::string& ENG,
const std::string& nazwa_pliku)
{
// app - dopisujemy do konca pliku
std::fstream od(nazwa_pliku, std::ios::app);
od << PL << " " << ENG << std::endl;
}
std::pair<Slownik, Slownik> wczytaj_slowa_z_pliku(const std::string& nazwa_pliku)
{
// para slownikow, ktora zwrocimy po wczytaniu wszystkich slow
std::pair<Slownik,Slownik> para;
int liczba_slow = 0;
std::ifstream od(nazwa_pliku);
std::string polskie;
std::string angielskie;
// najpierw wczytujemy liczbe slow
od >> liczba_slow;
if (!od) {
std::cerr << "Nie udalo sie wczytac slow z pliku\n";
exit(1);
}
// ta petla wczyta dowolna liczbe par slow - nie bierzemy pod uwage
// wartosci liczba_slow
while (od >> polskie >> angielskie) {
dodaj_slowo_do_slownika(polskie, angielskie, para);
}
return para;
}
void wyswietl_tlumaczenie(const std::string& szukany, ParaSlownikow& para)
{
// sprawdzamy czy slowo wystepuje w slowniku polsko-angielskim jako klucz
// tj. slowo polskie
if (para.first.find(szukany) != std::end(para.first)) {
// ...i wyswietlamy
std::cout << "Tlumaczenie: " << para.first[szukany] << std::endl;
// to samo dla ang.-pol.
} else if (para.second.find(szukany) != std::end(para.second)) {
std::cout << "Tlumaczenie: " << para.second[szukany] << std::endl;
} else {
std::cout << "Nie znaleziono tlumaczenia" << std::endl;
}
}
void wyswietl_slowa_na_litere(ParaSlownikow& para, char litera='\0', bool polskie=true)
{
// pomocnicza funkcja wyswietlajaca slowo, sprawdzajac wczesniej, czy jest
// na litere, po ktorej filtrujemy (jesli chcemy filtrowac - w przeciwnym
// razie zmienna litera ma wartosc domyslna - '\0'
auto wyswietl_slowa = [¶, &litera](Slownik slownik)
{
for (const auto& slowo : slownik) {
if (litera != '\0') {
// sprawdzamy pierwszy znak slowa
if (slowo.first.front() == litera) {
std::cout << slowo.first << "\t-\t" << slowo.second << std::endl;
}
} else {
std::cout << slowo.first << "\t-\t" << slowo.second << std::endl;
}
}
};
// jesli szukamy polskich, to wywolujemy powyzsza funkcje
if (polskie) {
// dla slownika pol.-ang.
wyswietl_slowa(para.first);
} else {
// w przeciwnym wypadku ang.-pol.
wyswietl_slowa(para.second);
}
}
void poprawa_literowki(ParaSlownikow& para,
const std::string& poprzednia_wersja,
const std::string& nowa_wersja)
{
// pomocnicza funkcja poprawiajaca literowke
auto popraw_slowo = [&poprzednia_wersja,&nowa_wersja](Slownik& s1, Slownik s2)
{
// najpierw zapisujemy sobie tlumaczenie danego slowa
std::string tlumaczenie = s1[poprzednia_wersja];
// usuwamy stara wersje slowa ze slownika s1
s1.erase(poprzednia_wersja);
// dodajemy nowa wersje
s1[nowa_wersja] = tlumaczenie;
// do drugiego slownika zapisujemy nowa wersje (slowo w przeciwnym
// jezyku, czyli tlumaczenie - zostaje bez zmian)
s2[tlumaczenie] = nowa_wersja;
};
if (para.first.find(poprzednia_wersja) != std::end(para.first)) {
// jesli to slowo polskie, to w powyzszej funkcji przyjmujemy:
// s1 - pol.-ang.
// s2 - ang.-pol.
popraw_slowo(para.first, para.second);
// no i zapisujemy poprawke do pliku
zapisz_caly_slownik_do_pliku(para.first, PLIK_SLOWNIK);
std::cout << "Poprawiono :-)!" << std::endl;
} else if (para.second.find(poprzednia_wersja) != std::end(para.second)) {
// analogicznie jesli to slowo angielskie
popraw_slowo(para.second, para.first);
zapisz_caly_slownik_do_pliku(para.first, PLIK_SLOWNIK);
std::cout << "Poprawiono :-)!" << std::endl;
} else {
std::cout << "Nie znaleziono slowa: " << poprzednia_wersja << std::endl;
}
}
int main()
{
bool koniec = 0;
auto para_slownikow = wczytaj_slowa_z_pliku("slowa.txt");
while (!koniec)
{
std::cout << "1. Slownik" << std::endl;
std::cout << "2. Dodaj do slownika" << std::endl;
std::cout << "3. Pokaz slownik" << std::endl;
std::cout << "4. Wygenerowanie strony" << std::endl;
std::cout << "5. Exit" << std::endl;
std::cout << "6. Wyswietl slowa na dana litere" << std::endl;
std::cout << "7. Popraw literowke" << std::endl;
char wybor = '\0';
std::cin >> wybor;
// wewnatrz instrukcji switch po prostu wywolujemy powyzsze funkcje
// zadnej magii ;-)
switch (wybor)
{
case '1':
{
std::string szukany;
std::cout << "Szukany wyraz: ";
std::cin >> szukany;
wyswietl_tlumaczenie(szukany, para_slownikow);
break;
}
case '2':
{
std::string PL;
std::string ENG;
std::cout << "Podaj PL" << std::endl;
std::cin >> PL;
std::cout << "Podaj ENG" << std::endl;
std::cin >> ENG;
dodaj_slowo_do_slownika(PL, ENG, para_slownikow);
dopisz_slowo_do_pliku(PL, ENG, "slowa.txt");
break;
}
case '3':
{
std::cout << "\n-----SLOWNIK-----\n" << std::endl;
wyswietl_slowa_na_litere(para_slownikow);
std::cout << std::endl;
break;
}
case '4':
{
std::ofstream od;
od.open("strona.html");
if (od.good()==false)
{
std::cout << "Plik nie istnieje!";
exit(1);
}
//html(od,tab,roz);
od.close();
std::cout << std::endl;
break;
}
case '5':
{
koniec = 1;
break;
}
case '6':
{
char litera = '\0';
std::cout << "Podaj litere, od ktorej maja zaczynac sie wyswietlone slowa: ";
std::cin >> litera;
wyswietl_slowa_na_litere(para_slownikow, litera);
break;
}
case '7':
{
std::string stara;
std::string nowa;
std::cout << "Podaj slowo, w ktorym chcesz poprawic literowke: ";
std::cin >> stara;
std::cout << "Podaj poprawiona wersje: ";
std::cin >> nowa;
poprawa_literowki(para_slownikow, stara, nowa);
break;
}
default: std::cout << "Wcisnieto niewlasciwy klawisz" << std::endl;
}
}
return 0;
}