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.



  • @daMicha

    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 sollte std::string sein und der Parameter könnte const& vertragen oder ein std::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 sollte std::string sein und der Parameter könnte const& vertragen oder ein std::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;
    

    😉


Anmelden zum Antworten