fgetc() und umlaute



  • Hallo Community!

    Ich habe hier ein kleines cat Programm gebaut, dass deutsche Umlaute umwandeln soll.
    Das Problem:
    Die Umlaute werden zwar korrekt erkannt und ersetzt, allerdings wird vor jedem Umlaut das Zeichen '195' ausgegeben.
    Hab den hässlichen Workaround unten auskommentiert.
    Frage, wo kommt dieses Zeichen her und wie komm ich da hübsch drumrum?

    Danke

    fivefinger

    #include <stdio.h>
    
    int main(int argc, char *argv[]) {
    	if (argc<2) {
    		printf("Too little arguments...\n");
    		return 1;
    	}
    	char *path=argv[1];
    	FILE *instream;
    	instream=fopen(path,"r");
    	if (instream==NULL) {
    		printf("File not found:%s\n",path);
    		return 1;	
    	}
    
    	int c;
    	while ((c = fgetc(instream)) != EOF) {
    		switch (c) {
    			case (unsigned char)'ö' :
    				printf("oe");
    				break;
    			case (unsigned char)'ä' :
    				printf("ae");
    				break;
    			case (unsigned char)'ü' :
    				printf("ue");
    				break;
    			case (unsigned char)'ß' :
    				printf("ss");
    				break;
    			/*case 195 :
    				break;*/
    			default :
    				printf("%c",c);
    				break;
    		}
    	}
    	return 0;
    }
    


  • kuck die textdatei die du einliest mal in nem hexeditor an, wahrscheinlich ist die nicht ANSI-kodiert.



  • loki1985 schrieb:

    kuck die textdatei die du einliest mal in nem hexeditor an, wahrscheinlich ist die nicht ANSI-kodiert.

    Die Datei ist utf-8 codiert.
    Wenn ich den ganzen switch-Block weglasse und einfach Zeichenweise ausgebe, werden die Sonderzeichen auch korrekt ausgegeben.



  • erstens: die windows konsole kann kein UTF, daher wirds wohl geschluckt.
    zweitens: so wie du die datei einliest erwartest du dass sie ANSI oder ASCII kodiert ist.

    die funktionen der C-standardlibrary sind nicht UTF8 kompatibel. fgetc zum beispiel gibt immer 1 byte zurueck, bei ASCII sind das dann auch korrekterweise chars, aber bei UTF eben nicht



  • loki1985 schrieb:

    erstens: die windows konsole kann kein UTF, daher wirds wohl geschluckt.

    Linux here. Locale ist utf-8.

    loki1985 schrieb:

    zweitens: so wie du die datei einliest erwartest du dass sie ANSI oder ASCII kodiert ist.die funktionen der C-standardlibrary sind nicht UTF8 kompatibel. fgetc zum beispiel gibt immer 1 byte zurueck, bei ASCII sind das dann auch korrekterweise chars, aber bei UTF eben nicht

    Daher der cast zu unsigned char.
    Und wie gesagt, sobald der switch Block weg ist und ich ihn durch ein einfaches

    printf("%c",c)
    

    ersetze, werden die Sonderzeichen fehlerlos ausgegeben.

    Vielleicht versteh ich deinen Hinweis auch nicht, hab wenig bis keine Ahnung von Zeichenkodierung.



  • loki1985 schrieb:

    fgetc zum beispiel gibt immer 1 byte zurueck, bei ASCII sind das dann auch korrekterweise chars, aber bei UTF eben nicht

    Nöh,

    int fgetc(FILE *stream);
    

    Richtig ist nur, daß das mit UTF nichts zu tun hat.



  • pointercrash() schrieb:

    loki1985 schrieb:

    fgetc zum beispiel gibt immer 1 byte zurueck, bei ASCII sind das dann auch korrekterweise chars, aber bei UTF eben nicht

    Nöh

    ok, dann halt korrekter: es gibt nen int zurueck, der das gelesene eine byte enthaelt, oder EOF im fehlerfall. meiner meinung nach macht das meine aussage nicht untrue, da ich den dateninhalt, nicht den datentyp gemeint habe.

    @fivefinger: wie gesagt, du liest bei jedem aufruf von fgetc() genau 1 byte ein. wie du aber im hexeditor sehen kannst verbraucht ein deutscher umlaut in der UTF8-kodierung mindestens 2 byte.

    heisst: entweder du stellst die kodierung der datei auf ASCII, oder du nutzt c-string-funktionen aus ner zusaeatzlichen library, oder baust dir funktionen die UTF8 pseudo-unterstuetzen.


Log in to reply