Switch und Umlaute umwandeln



  • 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.


Anmelden zum Antworten