Mosecode Übersetzer
-
@steven-w Copy&Paste hilft nicht beim Lernen! Also schreib das mal von Grund auf neu.
Probiere mal einen der c++ Container, wie z.B. eine std::map:
const std::map<unsigned char, std::string> morse_codes = { {'a', ".-"}, {'b', "-..."}, ... {'x', "-..-"}, {'y', "-.--"}, {'z', "--.."}, {'1', ".----"}, ... {'9', "----."}, {'0', "-----"} };
Vergleiche Deinen kopierten Code mit dem Internationalen Morse Alphabet. Da gibt es sogar Satzzeichen.
Eine der benötigten Funktionen könnte dann ungefähr so aussehen:
std::string string_to_morse(const std::string& text) { std::string data; for(unsigned char c text) { // das '_' ist der Zeichen-Delimiter data += "_" + morse_codes.find(std::tolower(c))->second; } return data; }
Für die zweite Funktion würde ich mir mal std::getline, den const Iterator und die String-Vergleichsfunktion compare etwas näher ansehen. Bei dem Parameter 'delim' von getline kommt unser '_' wieder ins Spiel:
std::string morse_to_string(const std::string& morse) { std::string data; std::string code; std::istringstream is(morse); while(std::getline(is, code, '_')) { // Finde den code in der std::map morse_codes // und füge den Buchstaben an data an. std::map<unsigned char,std::string>::const_iterator it = morse_codes.begin(); // ab hier machst Du weiter... } std::cout << data << std::endl; }
Viel Spass beim Basteln!
Edit: Hinweise von wob umgesetzt.
-
Danke für die Hilfe, ich schau mir das ganze an und werde wohl grundlegend damit nochmal neu anfangen.
-
@daMicha sagte in Mosecode Übersetzer:
std::istringstream is(text);
for(unsigned char c; is >> c; ) {Naja, warum gehst du hier eigentlich über eine Stream? Würde es nicht ein simples
for (char c : text) { ... }
auch tun?
Und für morse_to_string bietet sich doch eine umgekehrte map an anstatt die Map von char nach morsecode nach dem passenden Value zu durchsuchen. Auch ist deine Signatur
void morse2string(std::string morse)
fragwürdig. Returnwert solltestd::string
sein und der Parameter könnteconst&
vertragen oder einstd::string_view
sein.
-
@wob sagte in Mosecode Übersetzer:
for (char c : text) { ... }
auch tun?
Ja, das tut es. Und nach dem Ändern der Funktion sieht es sogar noch besser aus.
Und für morse_to_string bietet sich doch eine umgekehrte map an anstatt die Map von char nach morsecode nach dem passenden Value zu durchsuchen. Auch ist deine Signatur
void morse2string(std::string morse)
fragwürdig. Returnwert solltestd::string
sein und der Parameter könnteconst&
vertragen oder einstd::string_view
sein.Stimmt auch, Danke für den Hinweis.
std::string string_to_morse(const std::string& text); std::string morse_to_string(const std::string& morse);
Ich wollte nur eine map verwenden um Tip-Fehler zu vermeiden.
-
@daMicha sagte in Mosecode Übersetzer:
Ich wollte nur eine map verwenden um Tip-Fehler zu vermeiden.
Die Rückwärts-Map kannst du doch einfach aus der Vorwärts-Map erstellen. Selbstverständlich sollte man nicht 2x die Zuordnung hinschreiben!
Alternativ: https://www.boost.org/doc/libs/1_76_0/libs/bimap/doc/html/index.html (auch wenn ich mich mit der Boost-Dokumentation immer sehr schwer tue).
-
@wob sagte in Mosecode Übersetzer:
Die Rückwärts-Map kannst du doch einfach aus der Vorwärts-Map erstellen.
Definiere "einfach". Ich finde auf die Schnelle nur was mit Templates. Ob das dem OP wohl gut tut?
-
@daMicha sagte in Mosecode Übersetzer:
@wob sagte in Mosecode Übersetzer:
Die Rückwärts-Map kannst du doch einfach aus der Vorwärts-Map erstellen.
Definiere "einfach". Ich finde auf die Schnelle nur was mit Templates. Ob das dem OP wohl gut tut?
Hä? Deine Vorwärts-Map ist doch auch schon ein Template, weil eben std::map getemplatet ist.
const std::map<unsigned char, std::string> morse_codes = { {'a', ".-"}, {'b', "-..."}, ... }; [...] std::map<std::string, unsigned char> code_to_letter; for (const auto& l2c : morse_codes) code_to_letter[l2c.second] = l2c.first;
Diese for-Loop ist doch nun wirklich nicht kompliziert.
-
@wob ich hatte es inzwischen auch:
// umgekehrte map initialisieren std::map<std::string, unsigned char> string_codes; for(std::map<unsigned char, std::string>::const_iterator it = morse_codes.begin(); it != morse_codes.end(); ++it) { string_codes.insert(std::pair<std::string, unsigned char>(it->second, it->first)); }
Deins sieht besser aus, Du Profi!
-
@daMicha sagte in Mosecode Übersetzer:
Deins sieht besser aus, Du Profi!
Dein Code sieht halt nach C++98 aus. range-for und
auto
haben in C++11 vieles extrem vereinfacht.
-
@wob sagte in Mosecode Übersetzer:
std::map<std::string, unsigned char> code_to_letter; for (const auto& l2c : morse_codes) code_to_letter[l2c.second] = l2c.first;
std::map<std::string, unsigned char> code_to_letter; for (const auto& [letter, code] : morse_codes) code_to_letter[code] = letter;