[c++] Mit toupper Klein- in Großbuchst. umwandeln

Rofi

Erfahrenes Mitglied

Hi,

mit folgendem code wollte ich einzelne Zeichen von der Tastatur einlesen. Eigentlich sollten nach loslassen der einzelnen Tasten die Zeichen bereits umgewandelt am Bildschirm ausgegeben werden. So meine Vorstellung.
Statt dessen wird eingelesen bis zum Return und erst dann in der nächsten Zeile umgewandelt ausgegeben.
Der code stammt aus dem Buch C++ lernen u. professionell anwenden von Peter Prinz u. Ulla Kirch-Prinz. Ich glaube nicht, dass die beiden sich geirrt haben, aber es klappt nicht aus mir unerfindlichen Gründen.

Das Umwandeln klappt soweit bis auf die deutschen Umlaute (siehe Bild unten). Kann mir vielleicht jemand sagen, woran es liegen könnte.

Code:
// toupper
// Filter zur Umwandlung in Grossbuchstaben
#include <iostream>
#include <cctype>
using namespace std;
int main()
{
      char c;
      while (cin.get(c))		// solange einzelne Zeichen...
         {
            switch (c)
               {   case 'ä': c = 'Ä';		
	                              break;
                   case 'ö': c = 'Ö';
	                              break;
                   case 'ü': c = 'Ü'; 
                                              break;
                   case 'ß': cout.put('S'); c ='S';
                                              break;
                   default: c = toupper(c);	// restliche
                }
             cout.put(c);	// einzelnenes Zeichen ausgeben
          }
       return 0;
}

Bsp.:
 

Anhänge

  • toUpper.jpg
    toUpper.jpg
    34,4 KB · Aufrufe: 161
Zuletzt bearbeitet:
moin


Das Problem ist das cin.get() immer auf ein Return wartet.
Da wirst du wohl um den unschönen weg über getch() nicht herum kommen.
Außerdem ist das Umwandeln über switch schlecht, Rechne lieber um!


mfg
umbrasaxum
 
Hi.

Das Problem mit den Umlauten ist vermutlich, das du den Quelltext in einem Windows Editor geschrieben hast welcher einen Windows Zeichensatz zum Speichern verwendet (z.B. cp1252) wobei dein DOS Fenster vermutlich Codepage 437 bzw. 850 anwendet.

Z.B. hat das ä in der Codepage 437 den Code 132, im Windows Zeichensatz cp1252 allerdings den Code 228.

Wenn du also den Quelltext in einem DOS Editor lädst wirst du sehen welche Zeichen tatsächlich verarbeitet werden.

Gruß
 
Oops,

hab erst jetzt die Kurve gekriegt reinzuschauen :eek:

Ja genau Deepthroat, Microsoft Visual c++! Sowas in der Art wie Du es beschreibst muss es sein. Werde der Sache auf den Grund gehn!

Kann es evtl. auch sein, dass in bestimmten Fällen beim ASCII-Code ein Überlauf bereits bei 127 stattfinden kann. Ich dachte, dass es bis 255 geht?
'ä' hat den Wert 132 im ASCII-Code. Gebe ich ä ein, hat c im Überwachungsfenster den Wert -124 und 256 -124 = 132.
Oder müsste es doch 255-124=131 sein? Dann geht die Rechnung aber nicht auf, oder?
 
Zuletzt bearbeitet:
Bin ein Stückchen weitergekommen, glaube ich.
Es muss damit zu tun haben, dass der Datentyp char 256 mögliche Zeichenwerte hat. Aber der Wertebereich geht nicht von 0-255 (das wäre unsigned char), wie ich zuerst angenommen hatte, sondern von -128 bis +127!
Die deutschen Umlaute haben die folgenden Werte im ASCII-Code: ü=129; ä=132; ö=148; ß=225. Also alle oberhalb von 127!"
Wird 127 überschritten, müsste eigentlich im negativen Bereich wieder begonnen werden. Aus 128 wird also der Wert -128, aus 129 wird -127 usw. bis aus 132(ä) -124 wird. Ich brauche also einen anderen, grösseren Datentyp!

Habe auch schon mit unsigned char probiert (Wertebereich 0-255), aber da erhalte ich folgende Fehlermeldung:
"Run-Time Check Failure #3 - The variable 'c' is being used without being defined."

So, werde mich wieder melden....
 
Zuletzt bearbeitet:
Hi.

Du brauchst keinen anderen Datentyp. char reicht völlig aus.

Code:
char ae = '\x84'; // Zeichen 132 dezimal == 'ä' in Codepage 850
char Ae = '\x8e'; // Zeichen 142 dezimal == 'Ä' in Codepage 850

char c;
cin.get(c);
if (c == ae) cout << Ae;

Du könntest natürlich deinen Code auch einfach im DOS Zeichensatz speichern bzw. konvertieren.

Gruß
 
Genial, so klappts!

Tut mir leid, dass ich nicht regelmäßig antworten kann, wollte nicht undankbar sein!

Hier funktionierender
Code:
// toupper
// Filter zur Umwandlung in Grossbuchstaben
#include <iostream>
using namespace std;

char ae = '\x84'; // Zeichen 132 dezimal == 'ä' in Codepage 850
char Ae = '\x8e'; // Zeichen 142 dezimal == 'Ä' in Codepage 850
char oe = '\x94'; // Zeichen 148 dezimal == 'ö' in Codepage 850
char Oe = '\x99'; // Zeichen 153 dezimal == 'Ö' in Codepage 850
char ue = '\x81'; // Zeichen 129 dezimal == 'ü' in Codepage 850
char Ue = '\x9a'; // Zeichen 154 dezimal == 'Ü' in Codepage 850
char ss = '\xe1'; // Zeichen 225 dezimal == 'ß' in Codepage 850

int main()
{
    char c, ch;
		
    while (cin.get(c)){
         if (c==ae)      cout << Ae;
         else if (c==oe) cout << Oe;
         else if (c==ue) cout << Ue;
         else if (c==ss) cout << "SS";
         else{
              ch = toupper(c);
              cout << ch;} 
             //cout << toupper(c);
         };
    return 0;
}

Eines verstehe ich zwar immer noch nicht. Gebe ich nach dem letzten "else" das c mit "cout << toupper(c)" aus erhalte ich den Zahlencode (siehe unten).
Setze ich c aber in die Puffervariable ch und gebe sie so aus, klappt es! Warum
 

Anhänge

  • toupper_1.jpg
    toupper_1.jpg
    21,3 KB · Aufrufe: 2.722
  • toupper_2.jpg
    toupper_2.jpg
    22,8 KB · Aufrufe: 2.725
Zuletzt bearbeitet:
Rofi hat gesagt.:
Eines verstehe ich zwar immer noch nicht. Gebe ich nach dem letzten "else" das c mit "cout << toupper(c)" aus erhalte ich den Zahlencode (siehe unten).
Setze ich c aber in die Puffervariable ch und gebe sie so aus, klappt es! Warum
Das liegt daran das die Funktion toupper einen int zurückgibt. Der int wird dann ganz normal auch als Integer auf der Standardausgabe ausgegeben. Wenn du möchtest das der Wert als Zeichen ausgeben wird mußt du einfach casten. Das kannst du wie in C machen oder aber den static_cast von C++ benutzen:
Code:
cout << (char)toupper(ch);                 // old-style C cast
cout << static_cast<char>(toupper(ch));    // C++ static cast
Gruß
 
Perfekt, genau das war's!

Danke Dir deepthroat

main()
Code:
int main()
{
    char c;
		
    while (cin.get(c)){                  // solange Zeicheneingabe...
         if (c==ae)      cout << Ae;     // wenn 'ä' dann 'Ä'
         else if (c==oe) cout << Oe;     // wenn 'ö' dann 'Ö'
         else if (c==ue) cout << Ue;     // wenn 'ü' dann 'Ü'
         else if (c==ss) cout << "SS";   // wenn 'ß' dann 'SS'
         else cout << static_cast<char>(toupper(c)); // andere...
         };
    return 0;
}

Hm, das mit switch klappt nicht, hab den Teil wieder gelöscht? :(
 
Zuletzt bearbeitet:
Zurück