2 tablice string i przyporządkowanie znaków

0

Witam
Mam problem na moim etapie wiedzy nie do przejścia, a dla Was pewnie bułka z masłem. Chodzi i to, że muszę napisać program tłumaczący tekst na morsa. Wiem... jest tego w necie trochę, tylko, że nic z tych wszystkich pomocy nie rozumiem. A to trzeba jak krowie na granicy, krok po kroku. Otóż. zrobiłem 2 tablice (string) - w jednej alfabet, w drugiej kropki i kreski. Teraz tak, użytkownik wpisuje tekst, np. HELLO i program ma znaleźć, na jakich pozycjach w tablicy z alfabetem, są poszczególne litery z wyrazu HELLO, a następnie odwołać się do odpowiednich znaków, z tych samych pozycji, z drugiej tablicy z morsem i w rezultacie wyświetlić tego morsa. Nie wiem jak to zrobić i już mi ręce opadają, bardzo bym prosił o pomoc. Napisałem do jet pory coś takiego:

#include<iostream>          
#include<string>
using namespace std;        
int main()
{
    string ALFHABET[]= {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
    string MORSE[] = {".- ","-... ","-.-. ","-.. ",". ","..-. ","--. ",".... ",".. ",".--- ","-.- ","-.. ","-- ","-. ","--- ",".--. ","--.- ",".-. ","... ","- ","..- ","...- ",".-- ","-..- ","-.-- ","--.. "};
    string kod;
    string tekst;
    int A
    cout << "Co chcesz zrobić?\n\n";
    cout << "(1) Tłumaczenie na morsa\n";
    cout << "(2) Tłumaczenie z morsa\n";
    cout << "Wybrałeś: ";
    cin >> A;
    if (A==1) 
{
       cout << "Tłumaczenie z morsa\n\n";
       cout << "Napisz tekst, który chcesz przetłumaczyć:\n\n";
       cin >> tekst;   
       getline(cin, tekst);    
       for (int i=0; i<tekst.length(); i++ )
       kod += MORSE (tekst[i]);                       //Wiem, że to jest źle, ale nie wiem co ma być, żeby było dobrze,
       cout << "Tłumaczenie na morsa: \n\n";     //coś mi się zdaje, że czegoś jeszcze brakuje, ale już mam papkę w głowie.
       cout << kod << endl;
       cout << "\n\n";
}
    if (A==2)
{                      // Tym się będę martwił później
0

Na pierwszy rzut oka 2 rzeczy:

  1. zamiast string ALFABET[] daj string ALFABET, resztę zostaw jak jest.
  2. kod += MORSE[tekst[i] - 'A']; - wynika to z: http://pl.wikipedia.org/wiki/ASCII i przy założeniu, że podawane są tylko wielkie litery.
    Może się przydać: http://www.cplusplus.com/reference/clibrary/cctype/toupper/

Lepszym rozwiązaniem byłoby skorzystanie z kontenera map: http://www.cplusplus.com/reference/stl/map/

0
  1. No to wymazałem [], ale wtedy też musiałem wymazać {}, bo się nie chciało kompilować
  2. Napisałem kod += MORSE[tekst[i] - 'A'], ale i tak nie działa, program się kompiluje, ale po wpisaniu wyrazu jakiegoś po prostu nic nie wyświetla.

A założenie jest takie, że wystarczą tylko te duże litery. Co do tego kontenera map, to już poza zasięgiem moim jeszcze, ale wiem, że można jakoś i bez tego.
Prawdę mówiąc, to już nie mam siły do tego durnego programu.

0
       cin >> tekst;  
       getline(cin, tekst);   

Po co dwa razy próbujesz wczytać tekst?

0

Usuń to getline, bo po tym co tam robisz razem z tym cin to w stringu tekst nie siedzi nic

0

Wielkie dzięki, teraz gra i bucy :)
Dopiero się tego wszystkiego uczę, więc to dla mnie wcale nie takie łatwe. Pewnie zaraz będę miał problem z działaniem w drugą stronę, ale jak coś to znowu Was poproszę o pomoc :)

0

No i wiedziałem, znowu utknąłem, tym razem na tłumaczeniu z morsa na litery, wpisuję tak:

cin >> tekst;
for (int i=0; i<tekst.length(); i++)
kod += ALFABET [tekst[i] - '??????'];
cout << kod << endl;

Wyszedłem z założenia, że zapis musi wyglądać analogicznie, ale oczywiście te 2 tablice string są różne i jak się domyślam ASCII też tu będzie miał jakieś znaczenie. Mam 2 pytania - co trzeba wpisać w miejsce '??????' no i właściwie dlaczego wcześniej to było A. Czytałem o tym ASCII, ale jakoś nie mogę tego ogarnąć.

0

Niestety źle myślisz - nie będzie analogicznie. Rozumiem, że poszczególne litery w morsie są oddzielone spacjami. W takim wypadku wczytujesz cin'em po kolei każdy zestaw kropek/kresek, znajdujesz indeks pod jakim taki zestaw znajduje się w tablicy MORSE i robisz kod += 'A' + ten_indeks;

0

Niestety nie rozumiem.

tablica z morsem wygląda tak:
string MORSE[] = {".- ","-... ","-.-. ","-.. ",". ","..-. ","--. ",".... ",".. ",".--- ","-.- ","-.. ","-- ","-. ","--- ",".--. ","--.- ",".-. ","... ","- ","..- ","...- ",".-- ","-..- ","-.-- ","--.. ",".--.- ",".-.- ","---. "};

no a potem wpisuję w takim razie:
cin >> tekst;
for (int i=0; i<tekst.length(); i++)
kod += 'A' + jakiś indeks; // No i to tu tutaj to jest dopiero zamotane. Indeks? Znaczy się, że mam jeszcze coś wcześniej dopisywać? Prosiłbym o takie wytłumaczenie

0

Prosiłbym o takie wytłumaczenie łopatologiczne. No i co robi tam to 'A'? Proszę pamiętać, że z C++ mam do czynienia jakieś 2 tygodnie i wiem pewnie tyle co nic

0

Kombinuję jak koń pod górę, ale oczywiście bez powodzenia. I do tego jeszcze jedna rzecz - jak zrobić, żeby program widział takie litery jak np. Ł lub Ó i tłumaczył je na kod, odpowiednio "• — • • —" i "— — — •". ??? Czyli, wpisuję ŁUK, a program tłumaczy te 3 litery (w tym polskie też). No i stały problem, o co już pytałem, jak to napisać w drugą stronę, żeby z kropek/kresek powstał normalny wyraz.

   cin >> tekst;   
   for (int i=0; i<tekst.length(); i++)
   kod += NO WŁAŚNIE NIE WIEM CO????????        
   cout << kod << endl;
0

Zdecydowanie brakuje Ci jeszcze wiedzy i umiejętności, a dawanie gotowego kodu nic nie da, bo się nic nie nauczysz.
To - 'A' wynika z tego, że każda litera jest tak naprawdę liczbą całkowitą, więc 'A' - 'A' daje zero, 'B' - 'A' daje jeden itd. Dzięki temu uzyskujesz indeks, na którym w tej tablicy stringów MORSE występuje string z odpowiednim ciągiem kropek i kresek. Wynika to z tego: http://pl.wikipedia.org/wiki/ASCII

Jak chcesz w drugą stronę to musisz znaleźć indeks pod którym w tej tablicy znajduje się podany przez użytkownika string odpowiadający literze i przy pomocy tego indeksu wyliczenie litery zwykłego alfabetu.
Czyli dla każdej litery w alfabecie Morse'a:
1)Wyszukujesz w tablicy MORSE string, który jest równy temu co wprowadził użytkownik
2)na podstawie tego indeksu wyliczasz literę zwykłego alfabetu ('A' + ten_indeks)

edit: niestety polskie litery nie mają kodów z przedziału między literami A-Z, musisz je obsługiwać dodatkowo. Wszytko jest tu http://pl.wikipedia.org/wiki/ASCII

0

Obsługa polskich liter to w ogóle osobna sprawa, która w C++ niekoniecznie różowo wygląda. ;)
Co do tego programu, to łatwiej (intuicyjniej) byłoby Ci użyć mapy litera->kod, np:

#include <map>
#include <string>
//...
std::map<char, std::string> kod;
kod['a'] = ".-";
kod['b'] = "-...";
//...

Mając taką mapę (i jeśli chcesz, to i drugą mapę "z powrotem", choć niekoniecznie), de/kodowanie staje się bardziej czytelne. ;)

0

No jak może mi nie brakować wiedzy, skoro ją zdobywam od kilkunastu dni. A z tym programem już 3 dzień się męczę, wiem... śmieszne.
Ale dobra nie wiem, nie umiem, poddaję się... Teoretycznie ja to wszystko rozumiem i jest logiczne, gorzej z przeniesieniem teorii działania na te dziwne dla mnie znaczki. Będę kombinował pewnie dalej, chociaż mam już serdecznie dość. W każdym razie dziękuję za pomoc.

0

Spokojnie, wszyscy przez to przechodzimy od czasu do czasu. ;) Odejdź od kompa na chwilę, zrób dwa przysiady, trzy pompki, zrób sobie kawę, przeczytaj fragment jakiejś książki, odpocznij. Niech się tam w głowie ułoży co się ma ułożyć. Jak wrócisz, to pomyśl na świeżo. ;)

0

No dobra, nie da się w jedną stronę to spróbuję z tymi mapami, zapewne zaraz znowu coś będzie nie tak, bo przecież nigdy nie może być normalnie. Jakby co to się dalej będę pytał.

0

Od razu mówię, że z tymi mapami mam do czynienia od pół godziny gdzieś. Napisałem tak:

#include<iostream>          
#include<string>
#include<map>
using namespace std;
int main()
{
   map <string, string> kod; // nie  wiem czy to w ogóle tak można napisać 2x string, ale jak pisałem char to był błąd kompilacji
   kod[" "] = " ";                // to w moim zamyśle ma być spacja, ale nie wiem czy będzie działać
   kod[".-"] = "A";
   kod["-..."] = "B";
   kod["-.-."] = "C";
   kod["-.."] = "D";
...
   cin >> tekst;
   cout << "Tumaczenie z morsa: "\n\n";
   cout << koden[tekst] << endl; // wyświetla tylko 1 znak i wcale się nie dziwię, ale co zrobić, żeby wyświetlało więcej, znowu pisać coś w tym stylu for (int i=0; i<tekst.length(); i++) ???

Np. użytkownik wpisuje: .- -... -.-. a program powinien, przetłumaczyć to na ABC, póki co wyświetla tylko A (ale co dopisać, żeby było ABC?)

0

Tam miało być oczywiście cout << kod[tekst] << endl; (a nie żadne koden, literówka)

0

...Tak, pisać coś w stylu tego for'a.
PS. Trochę za dużo kropek ;)

0

Dokładnie tak, musisz zrobić pętlę i przejechać po stringu. ;) litera na kod - to zwykły for, a w drugą stronę to najłatwiej byłoby zrobić za pomocą stringstream (czyli traktujesz swój string jak strumień), jechać pętlą po nim wyciągając kolejne stringi za pomocą operatora >> i wtedy je wyświetlać/zapisując korzystając z mapy. Zawile brzmi? To proste:

#include <sstream> // to jest od std::stringstream
//...
std::string decode_morse(const std::string& msg, const std::map<std::string, std::string>& code_map) { // funkcja zwraca string, przyjmuje przez referencję string i mapę string->string
    std::stringstream ss(msg);
    std::string morse_sequence; //wczytujemy do tego po kolei sekwencje kropka-kryska (...kropa-kryska, fotografia twego pyska :P)
    std::string decoded; // w tym stringu będziemy trzymać naszą dekodowaną wiadomość
    while (ss >> morse_sequence) { // spacje ignorowane
        decoded += ____ ; // co tutaj zrobisz, żeby decoded rosło o nową dekodowaną literę w każdej iteracji?
    }
    return decoded; // zwracamy wiadomość
}

Potrafisz uzupełnić tę lukę? :)
http://www.cplusplus.com/reference/stl/map/operator[]/

0

Dobra, ja mam dosyć. Nic już nie myślę, nic nie rozumiem, nic nie umiem, wszystko to jakieś popieprzone, sstringi jakieś, te mapy, fistaszki &. Głowa mnie boli, gorąco mi się z nerwów zrobiło. Już nic nie chcę, ani wiedzieć, ani rozumieć. Mam wrażenie, że mi wyłożyliście wszystko jak na tacy, tylko wyciągnąć rękę, ale widocznie za tępy jestem. Nigdy w życiu z tymi rzeczami nie miałem nic wspólnego, a raptem muszę pisać jakiś głupi program z morsem. Muszę odpocząć, bo nic do mnie już do mnie nie dociera.
A w ogóle to mi się to nawet nie kompiluje, bo pewnie wstawiłem nie tam gdzie trzeba... ehhh. Taki durny programik, a tyle nerwów.

0

Ehhh nie denerwuj się... skoro masz do czynienia z c++ od 2 tygodni i pewnie wcześniej z żadnym językiem konkretniej nic nie walczyłeś to nie masz prawa tego zrozumieć :p
Odłóż ten program na razie i pisz prostsze rzeczy. Ucz się z jakiejś książki po kolei i systematycznie(inaczej nic z tego nie będzie).

A gdzie mu tu ze stringstream'ami, referencjami, template'ami i ogólnie całą zabawą z kontenerami :p Imho zamiast brać się za używanie kontenerów z stl'a fajnie jest na początku napisać własne odpowiedniki. :p

0

Niestety muszę to zrobić do jutra wieczorem i nie dlatego, że mam taki kaprys tylko zadanie szkolne. Mam wykorzystać same tablice stringów, obsługę znaków specjalnych (np. ŁÓŹĄĘ, itd). W książce jakieś głupie przykłady na cyfrach, które mi nic nie pomagają, a skąd im się wzięło napisanie tego morsa to nie wiem, skoro w życiu nie miałem z tym do czynienia i to są dla mnie nowe rzeczy... być może sprawdzają umiejętność radzenia sobie w ekstremalnych warunkach. Dopiero co się nauczyłem do czego służy zwykły string... to że można tworzyć tablice to sobie sam doszedłem, ale mniejsza o to. Po prostu muszę przez to jakoś przebrnąć, ale bez korzystania z tych kontenerów i innych udziwnień, musi się dać jakoś tylko i wyłącznie dzięki tablicom string, ale jak powiedziałem, trochę to przerasta w tej chwili moje umiejętności. Więc się zlitujcie, Wy też kiedyś umieliście tyle co ja dzisiaj.

0

To nie tyle udziwnienia, co ułatwienia. ;P

No ale dobra, dorób do tego dekodowanie:

#include <iostream> // cin, cout itepe
#include <string> // stringi
#include <cctype> // tolower

int main() {
    using namespace std;
    string to_morse[] = {".-", "-...", "-.-."};
    string msg = "aabbcc";
    string encoded;
    for (unsigned int i = 0; i < msg.size(); ++i) {
        encoded += to_morse[tolower(msg[i]) - 'a'] + " ";
    }
    cout << encoded << '\n';
    
    return 0;
}
0

Powiem tylko jak to wygląda z mojego punktu widzenia:

  1. #include<cctype> i tolower // pierwszy raz na oczy widzę
  2. const unsigned int size_of_alphabet = 3; // to też tak średnio do mnie przemawia, szczególnie to unsigned (nie spotkałem się)

Jutro już z tym będę wojował, bo dzisiaj wypalony jestem totalnie, chociaż oczywiście i tak nie działa coś znowu, czemu mnie to nie dziwi.
Dziekuję za pomoc.
Zastanawia mnie tylko to, po co ktoś zadaje taki projekt do zrobienia komuś, kto zna same najbardziej podstawowe podstawy podstaw. Chyba po to, żeby się skutecznie zrazić. Gdyby nie to, że nie potrafię nigdy dać za wygraną, to już dawno bym wypieprzył ten gówniany program z kompa i zajął się czymś innym.

0

Hej ;) mam mały (a dla mnie spory ;p) problem; mam do napisania program tłumaczący wyrazy, zdania itp. na alfabet morse'a. Poniżej podaję do wglądu część programu, którą napisałam, to działa tyle że tłumaczy tylko pierwszą literę i nic więcej. Co mam dopisać i gdzie aby program zaczął prawidłowo tłumaczyć całe zdania?
Z góry dzięki za pomoc ;)

#include <iostream>
#include <conio.h>
#include <cstdlib>
#include <string>
using namespace std;

string morse(char menu);
int main()
{
   string tekst;
   string wynik;
   cout << "Witam, prosze wprowadzic jakies slowo aby je przetlumaczyc na alfabet morse'a ";
   cin >> tekst;

   for(int i = 0; i < tekst.length(); i++)
   wynik = morse(tekst[i]);
   
   cout << "Podany wyraz w alfabecie morse'a brzmi: " << wynik << endl;
   
   string morse(char menu);

   system("PAUSE");
   return 0;
}
string morse(char menu)
{
    switch(menu)
    {
         case 'a': case 'A':
            return ".-";
         case 'b': case 'B':
            return "-...";
         case 'c': case 'C':
            return "-.-.";
         case 'd': case 'D':
            return "-..";
         case 'e': case 'E':
            return ".";
         case 'f': case'F':
             return "..-.";
         case 'g': case'G':
            return"--.";
         case 'h': case'H':
            return"....";
         case 'i': case'I':
            return"..";
         case 'j': case'J':
            return".---";
         case 'k': case'K':
            return"-.-";
         case 'l': case'L':
            return".-..";
         case 'm': case'M':
            return"--";
         case 'n': case'N':
            return"-.";
         case 'o': case'O':
            return"---";
         case 'p': case'P':
            return".--.";
         case 'q': case'Q':
            return"--.-";
         case 'r': case'R':
            return".-.";
         case 's': case'S':
            return"...";
         case 't': case'T':
            return"-";
         case 'u': case'U':
            return"..-";
         case 'v': case'V':
            return"...-";
         case 'w': case'W':
            return".--";
         case 'x': case'X':
            return"-..-";
         case 'y': case'Y':
            return"-.--";
         case 'z': case'Z':
            return"--..";
         case '1':
            return".----";
         case '2':
            return"..---";
         case '3':
            return"...--";
         case '4':
            return"....-";
         case '5':
            return".....";
         case '6':
            return"-....";
         case '7':
            return"--...";
         case '8':
            return"---..";
         case '9':
            return"----.";
         case '0':
            return"-----";
         case ' ':
            return "//";
            }
}
void glownydomorse(string tekst, string wynik)
{
}
0

Nie widzisz, że za każdym razem zamazujesz wynik przy zrwacaniu morse()?
Zamiast:
wynik = morse(tekst[i]);
daj:
wynik += morse(tekst[i]);
PS. Co do całych zdań: Poczytaj o getline() z klasy string.
PS2. Po co ci definicja funkcji w main?

0

Dzięki ;)
Jeszcze zaczęłam sobie coś po swojemu zmieniać i jest git - chcialam żeby ukośniki pokazywały się po każdej przetłumaczonej literze i dwa ukośniki po wyrazie i tak jest. Tyle że w pisaniu tekstu też muszę jak widac pisać ukośniki... a czy jest możliwość bez nich zadziałania? tzn. przykładowo teraz jest tak: pisze" A\L\A\2\4\" i dostaję: ".-/.-../.-..---/....-" a chcę pisać "ALA 24" i dostać to samo co poprzednio. Czy i jak można to zrobić?
Zajrzyjcie w program:

#include <iostream>
#include <conio.h>
#include <cstdlib>
#include <string>
using namespace std;

string morse(char menu);
int main()
{
   string tekst;
   string wynik;
   cout << "Witam, prosze wprowadzic slowo, ktore ma zostac przetlumaczone na alfabet morse'a ";
   cin >> tekst;

   for(int i = 0; i < tekst.length(); i++)
   wynik += morse(tekst[i]);
   
   cout << "Podany wyraz w alfabecie morse'a brzmi: " << wynik << endl;
   
   string morse(char menu);

   getch();
   return 0;
}
string morse(char menu)
{
    switch(menu)
    {
         case 'a': case 'A':
            return ".-";
         case 'b': case 'B':
            return "-...";
         case 'c': case 'C':
            return "-.-.";
         case 'd': case 'D':
            return "-..";
         case 'e': case 'E':
            return ".";
         case 'f': case'F':
             return "..-.";
         case 'g': case'G':
            return"--.";
         case 'h': case'H':
            return"....";
         case 'i': case'I':
            return"..";
         case 'j': case'J':
            return".---";
         case 'k': case'K':
            return"-.-";
         case 'l': case'L':
            return".-..";
         case 'm': case'M':
            return"--";
         case 'n': case'N':
            return"-.";
         case 'o': case'O':
            return"---";
         case 'p': case'P':
            return".--.";
         case 'q': case'Q':
            return"--.-";
         case 'r': case'R':
            return".-.";
         case 's': case'S':
            return"...";
         case 't': case'T':
            return"-";
         case 'u': case'U':
            return"..-";
         case 'v': case'V':
            return"...-";
         case 'w': case'W':
            return".--";
         case 'x': case'X':
            return"-..-";
         case 'y': case'Y':
            return"-.--";
         case 'z': case'Z':
            return"--..";
         case '1':
            return".----";
         case '2':
            return"..---";
         case '3':
            return"...--";
         case '4':
            return"....-";
         case '5':
            return".....";
         case '6':
            return"-....";
         case '7':
            return"--...";
         case '8':
            return"---..";
         case '9':
            return"----.";
         case '0':
            return"-----";
         case '\\':
            return "/";
            }
}
void glownydomorse(string tekst, string wynik)
{
}
0

aby rozwiazac ten problem, przede wszytkim musisz sobie odpowiedziec na pytanie:
w tekscie ktory ktos Ci podaje, czym się różni przerwa miedzy słowami od przerwy między zdaniami?
jesli dasz rade odpowiedziec na to pytanie, to dasz rade w programie sprawdzic typ przerwy i wypisac zamiast niej albo / albo //, nawet w podobny sposob jak to robisz teraz, acz rozwiazanie wybrales troche koslawe:)

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