C: Sonderzeichen werden nicht korrekt angezeigt



  • Hi(gh)!

    Ich habe angefangen, ein C-Lehrbuch (Helmut ERLENKÖTTER: C - Bibliotheksfunktionen sicher anwenden, Rowohlt 2003) durchzuarbeiten und bin bei der Übungsaufgabe Nr. 7 (S. 59) auf ein Problem gestoßen:

    /* Helmut ERLENKÖTTER, C - Bibliotheksfunktionen sicher anwenden */
    /* Aufgabe 7, S. 59 */
    
    #include <stdio.h>
    
    int main()
    {
      unsigned char c=32;
      short row;
      short col;
    
      for (row=0; row<16; row++)
      {
        for (col=0; col<14; col++)
        {
          printf("%c ", 32+row+col*16);
          if (col==13)
    	printf("\n");
        }
      }
      return 0;
    }
    

    Dieses Programm soll sämtliche ASCII-Zeichen ab Code 32 spaltenweise darstellen... leider werden alle Zeichen ab Code 128 (also auch alle deutschen Sonderzeichen) nur als schwarze Ellipsen mit inversem Fragezeichen angezeigt! Wie kann ich diese Zeichen korrekt anzeigen lassen?

    Mein Betriebssystem ist Linux (Debian aptosid "Geras"), der verwendete Compiler ist g++ 4.7.1.

    Bis bald im Khyberspace!

    Yadgar

    Now playing: Paradox (Synergy)



  • ASCII geht nur bis 127. Darüber hinaus gehen wohl deine Meinung und die deiner Konsole über die Zeichenkodierung auseinander.



  • Hi(gh)!

    MFK schrieb:

    ASCII geht nur bis 127. Darüber hinaus gehen wohl deine Meinung und die deiner Konsole über die Zeichenkodierung auseinander.

    Stimmt, die Kodierung meiner bash war auf UTF-8 eingestellt... und naiverweise war ich bis jetzt davon ausgegangen, dass UTF-8 eine 8bittige Kodierung sei und die hierzulande üblichen Sonderzeichen zwischen 128 und 255 zu finden seien.

    Der Wikipedia-Artikel zu UTF-8 belehrte mich dann aber eines Besseren, genannter Bereich enthält Flags für eventuell noch folgende höhere Bytes und eben keine konkreten Schriftzeichen!

    Ich habe dann einfach die bash auf das gute alte IBM850 umgestellt, das entspricht dann am ehesten dem Ausdruck-Beispiel im Lehrbuch... und hat außerdem dieses nostalgische Commodore 64-Feeling!

    Deppenfrage: kann ich mit C/C++ eigentlich auch "eigenmächtig" aus dem Programm heraus die Kodierung der Shell ändern?

    Bis bald im Khyberspace!

    Yadgar



  • Wie wäre es hiermit?

    [cpp]
    #include <stdio.h> 
    #include <stdlib.h>
    #include <locale.h>
    
    #define PRINT_FROM_HERE 32
    
    int main(void) 
    { 
        short row; 
        short col; 
    
        setlocale(LC_ALL, "");
    
        for (row=0; row<16; row++) { 
            for (col=0; col<14; col++) {
                printf("%lc ", (unsigned int) PRINT_FROM_HERE + row + col * 16); 
                if (col==13)
                    printf("\n");
            } 
        } 
        exit(EXIT_SUCCESS); 
    }
    [/cpp]
    

    Das Ergebnis sollte bei Linux und verwendetem UTF-8 zum korrekten Ergebnis führen (siehe Bildlink ... http://666kb.com/i/c71fv0w5td72l9l3c.png)



  • Hi(gh)!

    skbierm schrieb:

    Das Ergebnis sollte bei Linux und verwendetem UTF-8 zum korrekten Ergebnis führen (siehe Bildlink ... http://666kb.com/i/c71fv0w5td72l9l3c.png)

    Tut es leider nicht... sieht immer noch genauso aus wie vorher!

    Ich frage deswegen nach einer solchen Lösung, weil nur mit UTF-8 die Hochkommata in den Warnungen und Fehlermeldungen korrekt angezeigt werden...

    Bis bald im Khyberspace!

    Yadgar



  • Die Zeichen sind in Unicode alle vorhanden, nur eben an einer anderen Stelle. Ich würde daher nicht an so einem alten Legacyencoding festhalten und lieber gleich Unicode (UTF-8) einsetzen. Hier gibt es sogar eine offizielle Tabelle http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT Du musst die Unicodecodepoints halt noch als UTF-8 kodieren.



  • skbierm schrieb:

    for (row=0; row<16; row++) { 
            for (col=0; col<14; col++) {
                printf("%lc ", (unsigned int) PRINT_FROM_HERE + row + col * 16); 
                if (col==13)
                    printf("\n");
            } 
        }
    

    Was soll denn das if da?
    Das printf("\n"); gehört einfach hinter die for-col-Schleife.



  • skbierm schrieb:

    Wie wäre es hiermit?

    "%lc" ist erst C95 und verlangt wint_t und nicht unsigned int:

    http://ideone.com/AiX5Y



  • Wutz schrieb:

    "%lc" ist erst C95

    Ja, und? Wir haben 2012. Der aktuelle C-Standard ist C11. Bei jeder Erwähnung von Features, die nicht schon in Prä-K&R-C enthalten waren, kommst du daher und merkst das an, als sei es etwas schlechtes.

    Bei C++ stellst du dich doch auch nicht so an und benutzt fröhlich C++11-Features. Warum soll die C-Welt dann unbedingt auf dem Stand von 1989 zurückgehalten werden?


  • Mod

    mieser Schimmler schrieb:

    Warum soll die C-Welt dann unbedingt auf dem Stand von 1989 zurückgehalten werden?

    Compilerunterstützung.



  • SeppJ schrieb:

    Compilerunterstützung.

    Die meisten relevanten Compiler unterstützen zumindest C99. Einzige Ausnahme ist Microsoft. Die haben allerdings auch deutlich klar gemacht, dass sie nicht vor haben aktuellere C-Standards überhaupt jemals zu unterstützen. Von daher würde ich da keine Rücksicht mehr drauf nehmen. Die Alternative wäre auf ewig bei C89 zu bleiben. Nicht gerade attraktiv, finde ich.

    Unter Unix-Systemen ist C99-Unterstützung hingegen mehr als gängig und C erfreut sich nach wie vor größerer Verbreitung. Hier eine gemeinsame, über C89 hinausgehende, aber standardisierte Basis zu haben, ist imho durchaus sinnvoll. Die Vergangenheit hat leider gezeigt, dass das Fehlen einer solchen viele Entwickler zur Nutzung system- oder compilerspezifischer Features verleitet, was wohl kaum besser ist.

    C99 und C11 bieten imho einfach zu große Vorteile (gerade auch was das Schreiben von portablem Code angeht) als dass man sich wirklich auf Dauer auf C89 beschränken will.

    Und wenn wir jetzt mal mehr oder weniger obskure Embeddedsysteme ohne GCC-Unterstützung ausnehmen (die haben meist noch ganz andere Eigenheiten wie fehlende Stdlib u.ä.), sieht es mit der Unterstützung von zumindest C99 eigentlich gar nicht mal so schlecht aus. GCC/MinGW erzeugt auch Windows-Binaries. Mit Clang steht ein weiterer freier Compiler zur Verfügung, an dem man sich bedienen kann. Zum Beispiel könnten Compilervendors ihren eigenen alten Mist auch einfach in den Ruhestand schicken. Minix (Research-OS) hat das z.B. so gemacht, indem sie ihren alternden Systemcompiler (ACK) durch Clang ersetzt haben. Auch für kommerzielle Compilerhersteller nicht undenkbar.


  • Mod

    mieser Schimmler schrieb:

    SeppJ schrieb:

    Compilerunterstützung.

    Die meisten relevanten Compiler unterstützen zumindest C99. Einzige Ausnahme ist Microsoft. Die haben allerdings auch deutlich klar gemacht, dass sie nicht vor haben aktuellere C-Standards überhaupt jemals zu unterstützen. Von daher würde ich da keine Rücksicht mehr drauf nehmen. Die Alternative wäre auf ewig bei C89 zu bleiben. Nicht gerade attraktiv, finde ich.

    Wo ist denn da die Logik? Weil Microsoft sagt, niemals C99 zu unterstützen benutzt man C99? Microsofts Compiler ist der relevante Compiler für Windows. Warum hält man sich denn an den Standard? Weil Programme dann portabel sind! Aber was nützt einem ein C99-portables Programm, wenn es dann auf der meistverbreiteten Plattform nur mit Frickeln übersetzbar ist?

    Wenn du nur für Linux entwickelst darfste natürlich voll in reinhauen, was C11 angeht.



  • SeppJ schrieb:

    Wo ist denn da die Logik? Weil Microsoft sagt, niemals C99 zu unterstützen benutzt man C99?

    Genau. Wäre die Antwort jetzt "wir brauchen noch einige Zeit, sind aber zuversichtlich mit dem nächsten VS-Release C99 zu haben", dann würde ich wohl zähneknirschend noch eine Weile C89 unterstützen. Aber auf ewig auf C99+ zu verzichten, scheint mir hier einfach keine akzeptable Option zu sein. Ich akzeptiere es nicht, dass MS die C-Entwicklung bis in alle Ewigkeit zurückhält.

    Aber was nützt einem ein C99-portables Programm, wenn es dann auf der meistverbreiteten Plattform nur mit Frickeln übersetzbar ist?

    Wenn du mit GUI-Software auf den Büro- oder Consumer-Desktop abzielst, sicherlich. Bei Commandline- und Serversoftware ist der Anteil der Windowsnutzer erfahrungsgemäß nicht sonderlich groß. Von "meistverbreitete Plattform" ist da nichts zu sehen. Abgesehen davon ist das Übersetzen für Windows mit MinGW ja nun auch keine schlechte Alternative.

    Wenn du nur für Linux entwickelst darfste natürlich voll in reinhauen, was C11 angeht.

    Nicht nur für Linux, auch wenn das natürlich heute die wohl größte Anwendergruppe ist.



  • Hi(gh)!

    mieser Schimmler schrieb:

    Wutz schrieb:

    "%lc" ist erst C95

    Ja, und? Wir haben 2012. Der aktuelle C-Standard ist C11. Bei jeder Erwähnung von Features, die nicht schon in Prä-K&R-C enthalten waren, kommst du daher und merkst das an, als sei es etwas schlechtes.

    Oh, ein Traditionalist! Den Kernighan & Richie habe ich hier auch noch stehen, in einer Auflage von 1983...

    Bis bald im Khyberspace!

    Yadgar


Anmelden zum Antworten