ubuntuusers.de

Umlaute in C

Status: Gelöst | Ubuntu-Version: Ubuntu 9.04 (Jaunty Jackalope)
Antworten |

supeo

(Themenstarter)

Anmeldungsdatum:
25. Februar 2009

Beiträge: 23

Was ich mein ist, wie man auf diese Multibytes zugreifen kann. Wenn ich mir bspw. ein 'ä' ausgeben lasse, werden zwei Zahlen ausgegeben. Wie kann man mit diesen Zahlen rechnen, dh mit den einzelnen Zahlen?

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4677

Wohnort: Berlin

@supeo: Wenn Du da zwei Zahlen ausgeben kannst, musst Du ja irgendwie darauf zugreifen. Also weisst Du schon wie man drauf zugreift, sonst könntest Du sie nicht ausgeben. Ich verstehe die Frage also immer noch nicht? Und was willst Du da rechnen? Beim Suchen und Ersetzen rechnet man ja nicht mit den Zahlen, sondern ersetzt eine Folge von Bytes durch eine Andere.

Kannst Du vielleicht mal ein konkretes Problem nennen bei dem Du nicht weiter kommst? Welche Daten hast Du, in welcher Form, und was möchtest Du damit machen?

supeo

(Themenstarter)

Anmeldungsdatum:
25. Februar 2009

Beiträge: 23

Wenn ich ein mit UTF-8 kodierten Umlaut, bspw. 'ä', mit printf("%d", char zeichen); als Zahl ausgeben lasse, werden zwei Zahlen ausgegeben. Diese möchte ich einzeln mit anderen Zahlen vergleichen lassen. Ich möchte das Zeichen sozusagen zerlegen in die beiden Zahlen (Bytes). Wie?

Gruß

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4677

Wohnort: Berlin

Ich verstehe die Frage immer noch nicht. Wenn Du printf("%d", zeichen); ausführst, dann wird *eine* Zahl ausgegeben und nicht zwei. Also versuchs bitte mal mit einem Beispiel, dass man nachvollziehen kann. Und falls Du das da oben in einer Schleife ausführst, und deswegen zwei Zahlen ausgegeben werden, dann greifst Du ja schon auf beide Zahlen einzeln zu.

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6490

Wohnort: Hamburg

Was ich mein ist, wie man auf diese Multibytes zugreifen kann.

Dann liess dir den Wikipediaartikel durch und decodiere das selber. Anhand des ersten Bytes kannst du feststellen wieviele Bytes zu dem gesuchten Zeichen gehören.

Du must dann jeden String als Array von "unsigned char" interpretieren (aber nicht umwandeln). Zugriff etwa nach diesem Schema:

    ...
    char * eingabestring; /* sollte natürlich text enthalten */
    int i=0               /* Byteindex, beginnt mit 0 */
    unsigned char byte;   /* einzelnes Byte zur Weiterverarbeitung */

    byte = *(unsigned char *)(eingabestring + i);
    /* mach was damit */
    i++;
    ...

ist jetzt nur mal so als Idee hingeworfen, wobei ich hoffe das mir da jetzt keiner meiner berühmten Flüchtigkeitsfehler unterlaufen ist.

supeo

(Themenstarter)

Anmeldungsdatum:
25. Februar 2009

Beiträge: 23

Oh ja, ein kleiner Denkfehler von mir. Ich hab nicht drauf geachtet, dass das nächste Byte des Zeichens im nächsten Element ist. Meine Schleife hat schließlich genug Elemente ausgegeben, dabei hat der immer das letzte nicht ausgegeben, was mir aber deswegen nicht aufgefallen ist... mein Fehler.

Ich denke damit ist das gelöst. Ich danke euch allen herzlich.

Gruß, supeo

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4677

Wohnort: Berlin

Mal ein Versuch von mir:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
 * Replaces umlauts and 'sz' characters by their HTML entities.
 * 
 * @param input the UTF-8 encoded, zero terminated input string.
 * @returns newly allocated string with replaced characters.  Caller is
 *      responsible for freeing the memory.
 */
char* replace(char *input)
{
    /* 
     * Allocate enough memory for the worst case which is an input of
     * just 'sz' characters, each two bytes long, which will be replaced
     * by seven bytes ("ß").
     */
    char *result = malloc(strlen(input) * 6 + 1);
    char *replacement;
    int i, j;
    char c;
    
    i = j = 0;
    while ((c = input[i++])) {
        if (c == (char) 195) {
            switch ((unsigned char) input[i]) {
                case 164: replacement = "auml"; break;
                case 182: replacement = "ouml"; break;
                case 188: replacement = "uuml"; break;
                case 132: replacement = "Auml"; break;
                case 150: replacement = "Ouml"; break;
                case 156: replacement = "Uuml"; break;
                case 159: replacement = "szlig"; break;
                default: replacement = NULL;
            }
            if (replacement) {
                result[j++] = '&';
                while ((result[j++] = *replacement++));
                result[j - 1] = ';';
                ++i;
                continue;
            }
        }
        result[j++] = c;
    }
    result[j++] = '\0';
    return realloc(result, j);
}

supeo

(Themenstarter)

Anmeldungsdatum:
25. Februar 2009

Beiträge: 23

Ja, danke dir, ich hab das jetzt am Ende auch so ähnlich gemacht, nur mit negativen Werten. Gibt es irgendeine Funktion, um das Format einer Datei zu überprüfen?

Gruß

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4677

Wohnort: Berlin

Du meinst welche Kodierung verwendet wird? Nein gibt es nicht. Das muss man wissen, oder raten. Browser und Mailprogramm haben oft Code der versucht die Kodierung zu raten. So etwas würde ich in eigenen Programmen aber nicht unbedingt machen. Besser den Benutzer die Kodierung explizit angeben lassen.

supeo

(Themenstarter)

Anmeldungsdatum:
25. Februar 2009

Beiträge: 23

Gut, danke, damit ist dieses Thema wie ich das sehe endgültig gelöst. Noch einmal "Danke" für eure Hilfe.

Gruß

supeo

(Themenstarter)

Anmeldungsdatum:
25. Februar 2009

Beiträge: 23

Ja, danke, so hab ich das jetzt gemacht, funktioniert bestens. Danke für eure Hilfe.

Gruß

Antworten |