Umlaute ersetzen



  • Hallo ich habe folgendes Problem:
    Ich soll in einer Funktion eine Textdatei lesen, kopieren und in einer neuen Textdatei die gleichen Einträge schreiben, aber sämtliche ä durch ae,ü durch ue,ö durch oe,ß durch ss ersetzen.Die Textdatei enthält Einträge wie diesen:
    Krüßemeier,Jürgen,13.03.65,Lager
    Hier mein Quellcode, der aber nur immer einen Buchstaben ersetzen kann, also z.B. ü durch u leider nicht durch ue (da das dann mit ä und den anderen genauso geht, habe ich es stellvertretend erst mal mit dem ü ausprobiert).
    Und bei mir steht das ganze noch in der main, das mit der Funktion habe ich noch nicht so gerafft. Mein Ausbilder möchte das die Funktion
    umlauteEntfernen(char zeile[100]) heisst.
    BITTE dringend um Hilfe, ich bastel da schon seit einer Woche dran rum.
    [c][code]
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    int main(void) {

    FILE *ein, *aus;
    char c ;
    char z[100];
    char name_ein[255] ="C:/adressdaten.dat";
    char name_aus[255] = "C:/addressen.dat";

    ein=fopen(name_ein,"rb");
    if(ein == NULL) {
    printf("Konnte %s nicht finden bzw. oeffnen!\n",name_ein);
    return EXIT_FAILURE;
    }
    else {
    aus=fopen(name_aus,"w+b");

    if(aus==NULL) {
    printf("Konnte Zieldatei nicht erzeugen!\n");
    return EXIT_FAILURE;
    }
    else {

    /*Wir kopieren zeichenweise von ein nach aus */
    while( (c = getc(ein)) != EOF)

    {
    if(c == 'ü')
    {
    c = 'ue' ; // Hier gibt es die Fehlermeldung, das char nur
    // 1 Zeichen ersetzen kann, er ersétzt hier ü durch u
    }

    putc(c,aus);
    printf("Datei erzeugt, Umlaute erstzt\n");

    }
    }
    }

    return EXIT_SUCCESS;
    }



  • naja ein char kann auch nur ein Zeichen fassen!



  • Also ich würde es mit memcpy machen. So von wegen Zeiger auf nem *char ** laufen lassen und die Umlaute suchen. Jedes Mal, wenn ich einen gefunden habe kopiere ich alles dahinter in einen Hilfspuffer, ersetze den Umlaut und kopiere den Hilfpuffer wieder dahinter. Dann lasse ich den Zeiger weiterlaufen und das Spiel geht beim nächsten Umlaut wieder los.
    Ist das jetzt zu schwierig gedacht? Gibt's noch nen anderen Weg?

    [Edit] Ein paar Verbesserungen. :D[/Edit]



  • Also mit memcpy komme ich nicht klar.
    Wenn ein char nur einen Buchstaben fassen kann, kann ich den char vielleicht in einen anderen Datentyp umwandeln? Strings wie in C++ scheint es in C wohl nicht zu geben?
    Bitte helft mir, ich habe keine Lösungsansätze mehr.



  • ratter doch alles mit fgetc durch, mach fputc wenn kein umlaut, wenn doch dann 2 mal fputc mit den zu ersetzenden werten.. supereasy....



  • Hm. Die Signatur gefällt mir nicht besonders. Ich würde im Zweifel sowas bauen:

    char *strip_umlauts(char *dest, size_t n, char const *src) {
      int i;
      char const *p;
      for(i = 0, p = src; i < n - 1 && *p; ++p) {
        switch(*p) {
        case 'Ä': dest[i] = 'A'; dest[i + 1] = 'e'; i += 2; break;
        case 'Ö': dest[i] = 'O'; dest[i + 1] = 'e'; i += 2; break;
        case 'Ü': dest[i] = 'U'; dest[i + 1] = 'e'; i += 2; break;
        case 'ä': dest[i] = 'a'; dest[i + 1] = 'e'; i += 2; break;
        case 'ö': dest[i] = 'o'; dest[i + 1] = 'e'; i += 2; break;
        case 'ü': dest[i] = 'u'; dest[i + 1] = 'e'; i += 2; break;
        case 'ß': dest[i] = 's'; dest[i + 1] = 's'; i += 2; break;
        default:
          dest[i] = *p;
          ++i;
        }
      }
    
      dest[i] = 0;
      return dest;
    }
    

    Und dann halt so aufrufen:

    int main(void) {
      char buf[100];
      puts(strip_umlauts(buf, 100, "Hallo test test ÄÖÜäöüß test 1 3"));
      return 0;
    }
    


  • der folgende code ist mit visual müllhaufen getestet und funzt. hab deinen code auch ein bißchen optisch formatiert, damit auch niemad blind werden muß 😉

    #include <stdio.h>
    #include <stdlib.h>
    
    int
    main (int argc, char *argv[])
    { 
      FILE *ein,
           *aus;
      int   c; /* IN ANSI-C MUSS C EIN INT SEIN!!!!!! */
      char  name_ein[] = "C:/Addressen.ein.txt", /* die groesse 255 kannst du weglassen    */
            name_aus[] = "C:/Addressen.aus.txt"; /* dann nimmt der compiler automatisch so */
                                                 /* viel, wie der string benoetigt.        */
                                                 /* ausserdem sinnvollere namensgebung     */
      ein=fopen(name_ein,"rb");
      if(!ein) /* so testen die profis auf NULL ;) */
      {
        perror(name_ein);    /* eine aussagekräftige fehlermeldung */
        return EXIT_FAILURE; /* macht gleich viel mehr her         */
      }
      /* das unnötige geschachtel mit if-else etc sparen wir uns */
    
      aus=fopen(name_aus,"wb"); /* das '+' in "w+b" kannste weglassen,    */
      if(!aus)                  /* da die ausgabe eh nur geschrieben wird */
      {
        perror(name_aus);
        return EXIT_FAILURE;
      }
    
      /* Wir kopieren zeichenweise von ein nach aus */
      while(c=fgetc(ein), !feof(ein)) /* komma-operator ist cooler ;) */
      /* feof() anstelle von c!=EOF muss sein, weil fgetc() auch im fehlerfall EOF  */
      /* zurückgibt und dann nicht in die fehlerbehandlung unten für die eingabe    */
      /* kaeme. koennte man auch anders machen, aber so ists besser lesbar find ich */
      {
        if(ferror(ein)) /* fehlerbehandlung kann nicht schaden */
        {
          perror(name_ein);
          return EXIT_FAILURE;
        }
    
        switch(c)
        {
          /* bei meinem visual müllhaufen sind character-konstanten               */
          /* wohl signed char anstelle von int wie es ANSI-C vorschreibt!         */
          /* deswegen erst cast nach unsigned char damits anschliessend bei       */
          /* der vorzeichenbehafteten erweiterung nach int keine probleme gibt :/ */
          /* bei GNU-C kanst du sie casts weglassen                               */
    
          case (unsigned char)'ä': fputs("ae",aus); break;
          case (unsigned char)'Ä': fputs("AE",aus); break;
          case (unsigned char)'ö': fputs("oe",aus); break;
          case (unsigned char)'Ö': fputs("OE",aus); break;
          case (unsigned char)'ü': fputs("ue",aus); break;
          case (unsigned char)'Ü': fputs("UE",aus); break;
          case (unsigned char)'ß': fputs("ss",aus); break;
          default:                 fputc(c,aus);
        }        
    
        if(ferror(aus))
        {
          perror(name_aus);
          return EXIT_FAILURE;
        }
      }
    
      printf("Datei erzeugt, Umlaute erstezt\n");
    
      return EXIT_SUCCESS; 
    }
    


  • @ Konfusius
    Toll! Vielen Dank. Es funktioniert. Hätte ich nie hingekriegt.

    @Alle anderen
    Vielen Dank für eure Hilfe.
    Seit gestern Mittag habe ich versucht den Code von 0xdeadbeef bei mir einzubauen, ich habe mein Programm damit zwar nicht zum laufen gekriegt, aber 'ne ganze Menge über C gelernt. Muss ich wohl auch noch.
    🙂 🙂 🙂
    Tausend Dank nochmal an alle. Tolles Forum, nicht nur so eins wo man dumme Antworten kriegt.


Anmelden zum Antworten