Morsezeichen



  • Hallo,

    ich will einen code erstellen der ascii-zeichen in ein morsecode übersetzen soll.
    ich dachte da an zweidimensionale felder. nun zu meinem problem: die ascii-zeichen den feldelementen zuzuweisen ist kein problem (da jeweils nur ein zeichen pro feldelement) jedoch scheitert es bei der zuweisung des morsecodes:

    Ascii Morsecode
    A soll dieser string zugewiesen werden: -
    Ä soll dieser string zugewiesen werden: --
    B soll dieser string zugewiesen werden: -
    **
    C soll dieser string zugewiesen werden: --
    D soll dieser string zugewiesen werden: -**
    usw..

    hat jemand einen tip wie man jedem ascii-zeichen einen string zweisen kann?

    mfg speedy



  • std::map würde sich beispielsweise anbieten



  • vielen dank, werd gleich mal nachschlagen was das ist



  • Hallo

    Der Morsecode für ein einzelnes Zeichen läßt sich wenn nötig in ein Integer (oder sogar short) packen, mittels Bitoperationen. Zuerst definierst du ein gesetztes bit als Lang, ein nicht gesetzes Bit als kurz.
    Da Morsezeichen unterschiedlich viele Symbole haben können, must du auch noch die Anzahl im Interger unterbringen.
    Du teilst also ein 32-Bit Integer in zwei Teile auf : die erste (8 Bit) als Anzahl der Symbole und die anderen 24 die gesetzten Bits, ob lang oder kurz.

    /Edit : Also Zuordnung eines Morsezeichens zu dem KLarzeichen in ASCII eignet sich natürlich eine Map. Ich dachte du wolltest eine Methode wissen, um ein einzelnes Morsezeichen an sich zu verwalten.

    bis bald
    akari



  • deine annahme das ich nach einer methode suche ist richtig! auch dir danke ich herzlich!!! werd es so machen wie du es vorgeschlagen hast, mußt aber zuerst mehr über die bitoperationen lesen



  • --> akari

    könntest du ein kleines beispiel geben wie es in nem code aussieht?
    wäre dir dafür sehr verbunden!



  • Hallo

    Ich dachte da an sowas

    const unsigned short max_rep_len = 12; // Maximale Anzahl an Symbolen in einem Morsezeichen
    const char dot = '.'; // Representation des "Kurz"
    const char dash = '-'; // Representation des "Lang"
    
    // String-Repräsentation in Code packen
    unsigned short Code(const std::string& rep)
    {
      // Anzahl der Symbole in die ersten 4 Bits verschieben
      unsigned short code = (rep.size() << max_rep_len); 
      for (std::size_t lv = 0; lv < rep.size(); lv++)
      {
        // Jede einzelnes "Lang" als 1 eintragen
        if (rep[lv] == dash) code |= (1 << lv); 
      }
      return code;
    }
    
    // String-Repräsentation aus Code extrahieren
    std::string Decode(unsigned short code)
    {
      // Anzahl der Symbole exrahieren
      std::size_t len = (code >> max_rep_len); 
      // Ausgabestring mit passender Länge erstellen
      std::string rep(len, dot); 
      for (std::size_t lv = 0; lv < len; lv++)
      {
        // Jedes einzelne Bit auswerten und "Lang" setzen, wenn positiv
        if (code & (1 << lv)) rep[lv] = dash; 
      }
      return rep;
    }
    
    // Die Funktionen in einem Beispiel anwenden
    unsigned short a = Code(".-");
    unsigned short b = Code("-...");
    std::cout << "Code : " << a << "  " << b << std::endl;
    std::cout << "Decode : " << Decode(a) << "  " << Decode(b) << std::endl;
    

    Das kann natürlich noch optimiert werden, und auch eine Fehlerauswertung sollte rein.
    Vor allem würde ich das in eine Klasse kapseln, um es wie einen POD behandeln zu können.

    /Edit : Bemerkungen verbessert...

    bis bald
    akari



  • erstmal ein großes dankeschön für deine mühe akari!!!

    hab deinen code eingebunden und er läuft ohne probleme. bin jedoch ein blutiger anfänger und mir sind noch viele sachen unklar wie:

    // String-Repräsentation in Code packen
    unsigned short Code(const std::string& rep)
    

    std::string& rep ist eine referenz auf den datentyp std::string der in der klasse <string> definiert ist (richtig/falsch?). wieso benuzt du hier einen zeiger vor allem wenn es eine konstante ist bzw wieso defenierst du diese variable als eine konstante?

    // Anzahl der Symbole in die ersten 4 Bits verschieben
    unsigned short code = (rep.size( ) << max_rep_len);
    

    den ausdruck (rep.size( ) << max_rep_len); verstehe ich nicht. rep wurde oben deklariert, size( ) ist wahrscheinlich eine funktion der klasse <string> in die max_rep_len mit dem << operator geschrieben wird (richtig/falsch?). der datentyp short hat 16 bits zur verfügung, in rep.size( ) schreiben wir 12 rein die dem short zugewiesen werden, sprich rep.size( ) wandelt die 12 in 12 bits um und schreibt sie von hinten in den speicherplatz von code? wie aber werden die symbole in die ersten 4 bits verschoben?

    for (std::size_t lv = 0; lv < rep.size( ); lv++)
    

    std::size_t ist hier ein datentyp von lv, wie kommt das? könnte man hier also jede beliebige bezeichnung hinter std:: setzen, z.b.: std::wunschdatentyp?
    wieso benutzt du hier keinen "standard-datentypen" wie int für lv?

    // Jede einzelnes "Lang" als 1 eintragen
    if (rep[lv] == dash) code |= (1 << lv);
    

    hier wirds ganz düster..
    rep wird von einem zeiger zu einem feld mit lv elementen => rep[lv] ohne es vorher definiert zu haben und nach if (rep[lv] == dash) verzichtest du auf eine {} wie ist das möglich 😕 😮

    code |= (1 << lv);
    

    diese zeile gibt mir den rest :p
    code soll was zugewises werden, habe jedoch diesen operator |= nirgendwo gefunden. was passiert ausserdem in der klammer?

    viele fragen zu so einer späten stunde

    gruß speedy



  • 1. std::string ist der C++ Datentyp zur Verarbeitung von Strings (Zeichenketten) - und die Übergabe per konstanter Referenz (das ist kein Zeiger, auch wenn's ähnlich funktioniert) ermöglicht es dir, mit möglichst geringem Aufwand sowohl vorhandene Strings als auch char-Arrays zu übergeben (bei letzteren wird eine temporäre String-Variable erzeugt).

    (siehe auch meinen Artikel "Stringverarbeitung" im Magazin (klickst du da vv)

    2/3. string::size() liefert die Länge eines Strings zurück als size_t (das IST ein Standardtyp und stellt einen "ausreichend großen" vorzeichenlosen Ganzzahltyp dar). Und in diesem Fall hantiert der operator<< mit zwei eingebauten Typen (size_t und unsigned short), also greift die "normale" Bedeutung des Operators - und das ist ein Bit-Shift nach links

    4. Wie gesagt ist rep ein std::string - und der definiert sich den operator[] selber, so daß du auf die einzelnen Zeichen des Strings analog zu Arrays zugreifen kannst.

    5. |= ist ein sog. kombinierter Operator - und hat die selbe Wirkung wie code = code| (1 << lv); (dabei ist | eine bitweise OR-Verknüpfung und << der oben angesprochene Shift-Operator) - das Gebilde setzt das lv'te Bit in code auf 1.

    PS: Und die Klammern {} hinter dem if() etc sind nur nötig, wenn du dort mehrere Anweisungen zusammenfassen kannst 😉



  • hab das jetzt anders realisiert:

    #include <iostream>
    #include <string>
    using namespace std;
    void morsecode(char b);
    
    int main()
    {
    	string line;
    	cout << "string eingeben: " << endl; 
    	getline(cin,line);
    	transform(line.begin(),line.end(),line.begin(),ptr_fun(::toupper));
    	for (int i = 0; i < line.size(); i++)
    	 morsecode(line[i]);
    	cout << endl;
    	return 0;
    }
    
    void morsecode(char b)
    {
    	tabelle [ ] = {'A','B','C',...};
    	switch (b)
    	{
    		case 'A': cout << "*-    ";break;
            case 'B': cout << "-***  ";break;
    		case 'C': cout << "-*-*  ";break; 
            ...usw...
            default : cout << "Nicht erlaubte ASCII!!!";break;
    	}
    }
    

    danke für eure bemühungen 👍

    mfg speedy



  • Da stellt sich nur die Frage, wozu du das Array 'Tabelle' definiert hast, wenn du es doch nicht verwendest.



  • du hast vollkommen recht, deswegen korrektur!

    thx


Log in to reply