Umlaute konvertieren

Post Reply
Message
Author
tobi_odi
Posts: 18
Joined: 30. Dec 2003 22:27
Location: Dresden

Umlaute konvertieren

#1 Post by tobi_odi »

Ist eine Schwierigkeit überwunden, schon kommt das nächste Problem um die Ecke.

Ich möchte alle Umlaute in einer Datei für TeX in \"a; \"u; ... und so weiter mit einem C-Programm konvertieren.
Ich habe versucht das einzelne Zeichen als int mit switch() zu nutzen. Leider haben die Umlaute mehrere int Werte, so daß ich die Umlaute zwar herauslesen aber keine weitere Unterteilung machen kann. Wie kann ich auf die weiteren Werte zugreifen?

Zum testen habe ich mir eine Textdatei mit einigen Umlaute erstellt und sie mit dem folgenden Programm aufgerufen.

Code: Select all

#include <stdio.h>
#include <stdlib.h>

int main&#40;int argc, char **argv&#41;
&#123;
	if&#40;argc < 2&#41;
	return 2;
        char *file1 = argv&#91;1&#93;;
        int i=0, c;
	FILE *fp1;
        if&#40;&#40;fp1=fopen&#40;file1,"r"&#41;&#41; == NULL &#41;
        &#123;
		printf&#40;"zu lesende Datei %s nicht gefunden!\n", file1&#41;;
		return 11;
	&#125;
	while&#40;&#40;c=fgetc&#40;fp1&#41;&#41;!=EOF&#41;
	&#123;
		printf&#40;"%i %c\n",c,c&#41;;
		switch&#40;c&#41;
		&#123;
			case 195&#58; 
				&#123;
//??? Hier moechte ich gern auf den zweiten Wert zugreifen ???
					switch &#40;c&#41;
					&#123;
						case 164&#58; printf&#40;"\"a"&#41;;
							  break;
						case 132&#58; printf&#40;"\"A"&#41;;
						          break;
						// und so weiter
					&#125;
				&#125;
				break;
			default&#58;printf&#40;"%c",c&#41;;
				break;	
		&#125;	
	&#125;
		
	if &#40;!fclose&#40;fp1&#41;&#41;
	printf&#40;"Datei %s erfolgrein geschlossen!\n",file1&#41;;
	return 1;
	
&#125;
Gruß tobi

kaskadus

#2 Post by kaskadus »

Leider haben die Umlaute mehrere int Werte
:?: Es gibt den ANSI-Zeichensatz und den so genannten erweiterten Dos-Zeichensatz, die hier wohl wichtig sind.

Ä = C4 = 196 Ansi
Ä = 8E = 142 Dos-erw.

Richtige Tabellen suchen.
Unter Linux kannst du ANSI nehmen, für Windows-Konsole Dos-erw.

Im Internet gibt es da zuhauf Infos drüber.

User avatar
Lateralus
prolinux-forum-admin
Posts: 1238
Joined: 05. May 2004 7:35

#3 Post by Lateralus »

Hi

Ich denke mal, dass von UTF-8 die Rede ist, aber erstmal zu deinem Programm:

Dein Problem wird sein, dass du - wenn du mit getc ein neues Zeichen vor dem zweiten switch einliest - dieses Zeichen, welches ja auch ein potentielles 195 ist, verwirfst. Ein Lsg. dafür ist, zwei Funktionen getch und ungetch zu schreiben, welche das Zeichen nach Bedarf zurückstellen. (Die Idee kommt aus "Programmieren in C").

Code: Select all

#include <stdio.h>
#include <stdlib.h>

#define BUFSIZE  20

int buf&#91;BUFSIZE&#93;;
int buf_index=0;

int getch&#40;FILE *fp&#41;&#123;
  if&#40; buf_index == 0&#41;
    return getc&#40;fp&#41;;
  else&#123;
      return buf&#91;buf_index&#93;;
      buf_index--;
   &#125;

&#125;

void ungetch&#40;int c&#41;&#123;
   if&#40; buf_index >= BUFSIZE &#41;
      fprintf&#40;stderr, "Zeichen konnte nicht zurueckgestellt werden!\n"&#41;;
   else&#123;
      buf&#91;buf_index&#93; = c;
      buf_index++;
   &#125;

&#125;

int main&#40;int argc, char **argv&#41;
&#123;
   if&#40;argc < 2&#41;
   return 2;
        char *file1 = argv&#91;1&#93;;
        int i=0, c, oldc;
   FILE *fp1;
        if&#40;&#40;fp1=fopen&#40;file1,"r"&#41;&#41; == NULL &#41;
        &#123;
      printf&#40;"zu lesende Datei %s nicht gefunden!\n", file1&#41;;
      return 11;
   &#125;
   /* Wir benutzen getch&#58; */
   while&#40;&#40;c=getch&#40;fp1&#41;&#41;!=EOF&#41;
   &#123;
      printf&#40;"%i %c\n",c,c&#41;;
      oldc = c; /* Dies nur für den Fall, dass Switch mehrmals c liest, was ich nicht glaube  */
      switch&#40;oldc&#41;
      &#123;
         case 195&#58;
            &#123;
//??? Hier moechte ich gern auf den zweiten Wert zugreifen ???
/* Na dann los!&#58; */
               c = getch&#40;fp1&#41;;
               switch &#40;c&#41;
               &#123;
                  case 164&#58; printf&#40;"\"a"&#41;;
                       break;
                  case 132&#58; printf&#40;"\"A"&#41;;
                            break;
                  // und so weiter
         default&#58; ungetch&#40;c&#41;;
         break;
               &#125;
            &#125;
            break;
         default&#58;printf&#40;"%c",c&#41;;
            break;   
      &#125;   
   &#125;
      
   if &#40;!fclose&#40;fp1&#41;&#41;
   /* Den Schreibfehler könntest du mal korrigeren ;-&#41; */
   printf&#40;"Datei %s erfolgrein geschlossen!\n",file1&#41;;
   return 1;
   
&#125; 
So müsste es, denke ich funktionieren, auch wenn man das sicher noch schöner machen kann. Aber hasst du mal an ein awk-Skript gedacht? (Das funktioniert nur, wenn dir die Zeichen in der Shell korrekt ausgegeben werden.

Code: Select all

cat file | awk ' &#123; gsub&#40;"Ä", "\"A"&#41;; gsub&#40;"ä", "\"a"&#41;; &#91;...&#93; print;  &#125; ' > file.new
Würde dir file in file.new schreiben und dabei die Änderung vornehmen.

tobi_odi
Posts: 18
Joined: 30. Dec 2003 22:27
Location: Dresden

Vielen Dank für eure Tips, vor allem für den Einsatz von Lateralus !!!

#4 Post by tobi_odi »

Meine Konvertierung funktioniert perfekt.

Leider habe ich es noch nicht entgültig verstanden warum.
Wann wird der Wert buf_index vor dem Aufruf von getch mit einem Wert ungleich 0 gesetzt?

Gruß tobi

User avatar
Lateralus
prolinux-forum-admin
Posts: 1238
Joined: 05. May 2004 7:35

#5 Post by Lateralus »

Hi

buf_index wird nur von getch und ungetch benutzt und wird nur dann erhöht, wenn ungetch aufgerufen wird. Dies ist dann der Fall, wenn das auf 195 folgende Zeichen nicht 164 oder 132 entspricht. Hier das Code-Stück (auf default achten):

Code: Select all

         case 195&#58;
            &#123;
//??? Hier moechte ich gern auf den zweiten Wert zugreifen ???
/* Na dann los!&#58; */
               c = getch&#40;fp1&#41;;
               switch &#40;c&#41;
               &#123;
                  case 164&#58; printf&#40;"\"a"&#41;;
                       break;
                  case 132&#58; printf&#40;"\"A"&#41;;
                            break;
                  // und so weiter
         default&#58; ungetch&#40;c&#41;;
         break;
               &#125;
            &#125; 

Post Reply