Switch und Umlaute umwandeln
-
Abend,
ich habe hier ein kleines Programm mit welchem ich Umlate (ä,ö,ü usw.) in z.B. "ae" umwandeln möchte. Leider funktioniert meine switch-Verzweigung nicht richtig...aber wo liegt der Fehler!?
Die "case z" Verzweigung funktioniert perfekt, aber der Rest nicht... Wenn ich z.B. "0x84" in 'ä' ändere, klappt es auch nicht.
//Umlaute umwandeln #include <stdio.h> //Definition der Konstanten EOF und der makros getchar(), putchar() int main() { int c; while ((c = getchar()) != EOF) // Zeichen einzeln bis DateiENDE einlesen //{ switch (c) { case 0x84: //ä putchar('a'); putchar('e'); break; case 0x94: //ö putchar('o'); putchar('e'); break; case 0x81: //ü putchar('u'); putchar('e'); break; case 0xE1: //ß putchar('s'); putchar('s'); break; case 'z': // zum testen >>> funktioniert sogar!? warum der Rest nicht :( putchar('b'); break; default: putchar(c); //Jedes andere Zeichen unverändert ausgeben. break; //} } return 0; }
Tzzz...brauche wohl noch einen Kaffee. Danke schon jetzt für eure Mühe, bin gespannt wo der Hund begraben liegt.
-
Je nach Encoding werden die Umlaute unterschiedlich dargestellt, manchmal auch mit mehr als nur einem Byte.
Hast du schonmal die eingelesenen Werte vor dem switch direkt als int ausgegeben?Edit: Debian dürfte UTF-8 verwenden und damit zb "\xc3\xa4" für ä.
-
Hast Du schon mal überprüft, ob die Codes, die Du abfragst, korrekt sind?
... while ((c = getchar()) != EOF) // Zeichen einzeln bis DateiENDE einlesen { printf("\n* %d *\n", c); switch (c) { ...
-
Belli schrieb:
Hast Du schon mal überprüft, ob die Codes, die Du abfragst, korrekt sind?
... while ((c = getchar()) != EOF) // Zeichen einzeln bis DateiENDE einlesen { printf("\n* %d *\n", c); switch (c) { ...
Als Ausgabe erhalte ich für "abcdeä":
* 97 * * 98 * * 99 * * 100 * * 101 * * 195 * * 164 * * 10 *
Das seltsame ist, dass wenn ich ein 'z' eingebe auch korrekt ein 'b' ausgegeben wird.
Wenn ich "\xc3\xa4" für 'ä' eingebe funktioniert es auch nicht.
SELBST wenn ich 'ä' eingebe funktioniert es nicht also:
switch (c) { case 'ä': //ä putchar('a'); putchar('e'); break;
Führt zu Ausgabe: 'ä' und nicht 'ae'.
Hmmm... wenn es nie funktionieren würde... aber so!? warum funktioniert dann 'z' ?
-
cStarter12 schrieb:
Als Ausgabe erhalte ich für "abcdeä":
... * 195 * * 164 * * 10 *
Spannend ... das sieht aus, als wenn Dein 'ä' zwei getchar() - Aufrufe erfordert und dann 0xC3 und 0xA4 liefert:
switch (c) { case 0xC3: if(0xA4 == getchar()) { putchar('a'); putchar('e'); } break;
-
Ich würde vermuten ohne es getestet zu haben, dass ein char vorzeichenbehaftet ist und damit ein 'ä' einen negativen Wert darstellt...
Wie w#re es mit folgenden Testprogramm:
#include <stdio.h> main() { printf( "%d", 'ä' ); return 0; }
-
Wie ich bereits in der ersten Antwort geschrieben habe, wird in UTF-8 ein ä in zwei Bytes dargestellt: "\xc3\xa4"
Das wiederum ist ein String. Kann man mit einem switch("abc") strings vergleichen? Nein, es werden nur die Adressen der Strings verglichen.
C bietet standardmäßig keine Unterstützung für UTF-8.Ein 'ä' in deinem Code sollte auch eine Warnung der Art "Zeichenkonstante mit mehreren Zeichen" liefern.
-
Mhm, ich hätte erwartet, dass getchar() dann 0xC3A4 liefert, denn es gibt ja schließlich einen int zurück ...
Aber gut, so wie ich es oben skizziert habe, sollte es dann ja funktionieren.
-
man getchar schrieb:
fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, or EOF on end of file or error.
getc() is equivalent to fgetc() except that it may be implemented as a macro which evaluates stream more than once.
getchar() is equivalent to getc(stdin).
Wie gesagt, C hat da keine Unterstützung und man muss tricksen. Das neue C++11 soll es wohl (teilweise) unterstützen.
-
Belli schrieb:
Mhm, ich hätte erwartet, dass getchar() dann 0xC3A4 liefert, denn es gibt ja schließlich einen int zurück ...
Totaler Quatsch diese Schlussfolgerung; weswegen getchar und Konsorten int zurückliefern, hat einen ganz anderen Grund, der hier auch schon mehrfach ausführlich erläutert wurde.
-
lagalopex schrieb:
Wie gesagt, C hat da keine Unterstützung und man muss tricksen.
Man muss hier überhaupt nicht tricksen, man muss nur die (ohnehin sehr schmale) C89-Standardbibliothek kennen, z.B. fgetwc; sinnvoll ist hierfür natürlich auch die Kenntnis über und im Umgang mit wchar_t.
-
[quote="Wutz"]
Belli schrieb:
weswegen getchar und Konsorten int zurückliefern, hat einen ganz anderen Grund, der hier auch schon mehrfach ausführlich erläutert wurde.
Damit meinst Du aber nicht hier in diesem Thread?
-
Wutz schrieb:
lagalopex schrieb:
Wie gesagt, C hat da keine Unterstützung und man muss tricksen.
Man muss hier überhaupt nicht tricksen, man muss nur die (ohnehin sehr schmale) C89-Standardbibliothek kennen, z.B. fgetwc; sinnvoll ist hierfür natürlich auch die Kenntnis über und im Umgang mit wchar_t.
Ist jetzt nicht so, dass ich mit fgetwc schon groartig auseinander gesetzt habe, aber ein kleiner Test liefert WEOF wenn ich einen Umlaut eingebe. (Und setzt errno auf EILSEQ)
Und mein locales stehen alle auf UTF-8.