PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C] Umlaute vergleichen



roadracer
20-08-2010, 23:30
Hallo,
hab' ein kleines Problem mit Umlauten, und zwar: Ich will eine Datei zeichenweise auslesen, und prüfen ob das eingelesene Zeichen ein Umlaut ist. Das das so nicht funktioniert kann sich wohl jeder denken. Aber wie mache ich es richtig? Ich habe schon diese Seite gefunden http://www.cl.cam.ac.uk/~mgk25/unicode.html#linux (http://www.cl.cam.ac.uk/%7Emgk25/unicode.html#linux) nur werde ich ehrlich gesagt nicht so richtig schlau daraus. Gut, man soll einen anderen Zeichensatz verwenden, entweder den passenden Regionalen (bei mir also ISO 8859-1) oder UTF-8. Leider bekomme ich weder das eine noch das andere hin :o. Bitte also ein wenig vorkauen.
Hier mein Code mit dem das funktionieren soll:


#include <stdio.h>

int main () {
FILE *input, *output;
char c;
/* Dateien öffnen, NULL-Pointer abfangen, zeichenweise aus *input mit fgetc einlesen.*/
while ((c = fgetc (input)) != EOF) {
if (c == 'ä')
fprintf (output, "ae");
else if (c == 'ö')
fprintf (output, "oe");
else if (c == 'ü')
fprintf (output, "ue");
else if (c == 'Ä')
fprintf (output, "Ae");
else if (c == 'Ü')
fprintf (output, "Ue");
else if (c == 'Ö')
fprintf (output, "Oe");
else
fprintf (output, "%c", c);
}
/* ...*/
}

Der Franz
21-08-2010, 23:54
Das Problem ist natürlich, dass ein Umlaut in UTF-8 mehr als ein Zeichen ist.
Bei mir geht's zum Beispiel so (den String musst du natürlich durch deinen Input ersetzen)

#include <stdio.h>

int main() {
char *str = "ö ä ü";
unsigned char * c = str;
do {
if (*c == -64) {
++c;
if (*c == -74)
printf ("oe");
else if (*c == -92)
printf ("ae");
else if (*c == -68)
printf ("ue");
} else {
putchar (*c);
}
} while (*(c++));
}


PS.: Ö -> -106; Ä -> -124; Ü -> -100

jeebee
22-08-2010, 11:47
Dabei ist zu erwähnen, dass man nicht einen unsigned char mit einer negativen Konstante vergleichen sollte! Besser:
... if(*c == 192) { ... usw. Die Umrechnung ist wie folgt: (signed char) -64 == (unsigned char) 128 + 64.

Der Franz
22-08-2010, 17:12
Sry, es heißt doch -61.
Aber mit 195 (256-61, weil negative Zahlen im Zweierkompliment dargestellt werden), geht's nicht. Mit 189 (128 + 61) übrigens auch nicht.

roadracer
22-08-2010, 18:05
Entschuldigt die Frage, gibt es bei Zeigern einen Unterschied zwischen


char *c;
char* c;
char * c;?

Und was ist eigentlich
char **c?
Gibt es da auch irgendwelche Unterschiede?

undefined
22-08-2010, 19:36
Das erste ist eine C/C++ Glaubens frage in C schreibt man vor die Variable wobei man bei C++ dazu rät hinter die Deklaration zu schreiben.

Link - Die erste Zeile sagt viel aus ;)
http://www.proggen.org/doku.php?id=c:pointer

jeebee
22-08-2010, 20:04
Also bei mir funktioniert der Code aus post #2 (http://www.mrunix.de/forums/showpost.php?p=318937&postcount=2) funktioniert bei mir auch nicht, ausser ich lasse das unsigned in Zeile 5 weg.

edit: es lohnt sich wohl, für Unicode + C die GLib zu verwenden: http://library.gnome.org/devel/glib/unstable/glib-Unicode-Manipulation.html

roadracer
22-08-2010, 21:41
Das erste ist eine C/C++ Glaubens frage in C schreibt man vor die Variable wobei man bei C++ dazu rät hinter die Deklaration zu schreiben.

Link - Die erste Zeile sagt viel aus ;)
http://www.proggen.org/doku.php?id=c:pointer
Weist'e Bescheid, Schätzelein! :D
Okay danke, dann ist char * c; wohl ein Kompromiss. ;)

VG

undefined
23-08-2010, 06:11
Also bei der zweiten und dritten Variante würde ich dringend davon abraten das in C zu machen. Manche Compilern Interpretieren das ganz anders ;) http://www.peacesoftware.de/ckurs12.html

sommerfee
23-08-2010, 06:53
Also bei der zweiten und dritten Variante würde ich dringend davon abraten das in C zu machen. Manche Compilern Interpretieren das ganz anders ;)

Welche? Mir ist bisher kein derart fehlerhaft implementierter C-Compiler begegnet.

P.S.: Mein Tipp: http://madison-project.wikidot.com/local--files/tutorials/The_C_Programming_Language.pdf

roadracer
24-08-2010, 21:11
[...]es lohnt sich wohl, für Unicode + C die GLib zu verwenden: http://library.gnome.org/devel/glib/unstable/glib-Unicode-Manipulation.html

Danke, hört sich super an! Ich hab' mir das jetzt schon ein paar mal durchgelesen, und bin ich irgendwie 'n bissel zu dumm für UTF-8. Ich habe zwar Variablen-Typen für UTF-32 (gunichar) und UTF-16 (gunichar2) gefunden, aber keinen für UTF-8. :D

VG

roadracer
04-09-2010, 22:28
Die Methode von Der Franz funktioniert auf jeden Fall unter Linux.
Jetzt habe ich mich noch mal an eine "saubere" Variante mit wild characters versucht, aber irgendwie will mein System (Siehe Signatur) die nicht anzeigen. wprintf gibt als Rückgabe wert immer -1 zurück: Fehler.
Ich habe schon mal dieses kleine Beispiel Programm von der Seite hier http://www.wolf4you.de/doku/qr/c/printfexamples.htm laufen lassen, aber alles was mit wprintf ist wird einfach nicht angezeigt.

#include <stdio.h>

void main( void )
{
char ch = 'h', *string = "computer";
int count = -9234;
double fp = 251.7366;
wchar_t wch = L'w', *wstring = L"Unicode";

/* Display integers. */
printf( "Integer formats:\n"
"\tDecimal: %d Justified: %.6d Unsigned: %u\n",
count, count, count, count );

printf( "Decimal %d as:\n\tHex: %Xh C hex: 0x%x Octal: %o\n",
count, count, count, count );

/* Display in different radixes. */
printf( "Digits 10 equal:\n\tHex: %i Octal: %i Decimal: %i\n",
0x10, 010, 10 );

/* Display characters. */

printf("Characters in field (1):\n%10c%5hc%5C%5lc\n", ch, ch, wch, wch);
wprintf(L"Characters in field (2):\n%10C%5hc%5c%5lc\n", ch, ch, wch, wch);

/* Display strings. */

printf("Strings in field (1):\n%25s\n%25.4hs\n\t%S%25.3ls\n",
string, string, wstring, wstring);
wprintf(L"Strings in field (2):\n%25S\n%25.4hs\n\t%s%25.3ls\n",
string, string, wstring, wstring);

/* Display real numbers. */
printf( "Real numbers:\n\t%f %.2f %e %E\n", fp, fp, fp, fp );

/* Display pointer. */
printf( "\nAddress as:\t%p\n", &count);

/* Count characters printed. */
printf( "\nDisplay to here:\n" );
printf( "1234567890123456%n78901234567890\n", &count );
printf( "\tNumber displayed: %d\n\n", count );
}


VG roadracer

roadracer
06-09-2010, 16:46
Lösung gefunden. Man darf auf den jeweiligen Stream nur mit Wide-character- oder Multibyte-Funktionen zugreifen.
Also entweder nur printf oder nur wprintf!