Char zu "String".



  • Nubian schrieb:

    ...
    int  c;
    strcat(buffer, (char *)&c);
    

    hehe, das geht bestimmt nur auf little-endian kisten (x86 z.b.) wo sizeof(int) mindestens so gross ist wie 2*sizeof(char) 🙂



  • Hi,

    Auf die eine Teillösung Buffer[100] kam ich auch, aber was ist wenn der Dateiinhalt grösser ist?

    Gruss



  • johnny.xy schrieb:

    aber was ist wenn der Dateiinhalt grösser ist?

    abbrechen und den buffer verarbeiten bzw. einen anderen buffer füllen.
    du kannst auch den buffer so gross machen wie die ganze datei aber das ist nur für relativ kleine files ratsam



  • net schrieb:

    hehe, das geht bestimmt nur auf little-endian kisten (x86 z.b.) wo sizeof(int) mindestens so gross ist wie 2*sizeof(char) 🙂

    bei mir gehts 😃
    ist aber zugegeben nicht die feine art...

    johnny.xy schrieb:

    Hi,

    Auf die eine Teillösung Buffer[100] kam ich auch, aber was ist wenn der Dateiinhalt grösser ist?

    Gruss

    wenn du nicht weisst wie gross die datei ist (wird wohl meistens der fall sein) dann musste es eben mit realloc machen.
    Daniel E. hat das letztens mal runtergetippt, also verweise ich mal darauf statt es neu zu tippsen 😉

    Daniel E. schrieb:

    void* xrealloc(void *mem, size_t sz) {
        void *p = realloc(mem, sz);
    
        if (!p) {
            free(mem);
            ...
            exit(EXIT_FAILURE);
        }
    
        return p;
    }
    
    char *fgetfile(FILE *f) {
        char *p, *q;
        size_t mem_sz = INIT_MEM; /* beliebige Konstante */   
        size_t pos = 0;
    
        p = 0;
        while (1) {
             p = xrealloc(p, mem_sz);
    
             q = p + pos;
     
             while (q != p + mem_sz) {
                  int c = fgetc(f);
    
                  ++pos;
    
                  if (c == EOF) {
                      *q = '\0';
                      return p;
                  }
                  else *q++ = c;
             }
    
              mem_sz *= 2; /* Speicherbereich verdoppeln */
         }
    
         return 0; /* nie erreicht, wenn der Quelltext so tut, wie ich mir das vorstelle */
    }
    

    Das ist jetzt einfach so runtergehackt, also vermutlich ist irgendwo noch ein Fehler drin. Außerdem kann man die Sache etwas beschleunigen, indem man andere Leseroutinen statt fgetc verwendet ...

    Hast Du wirklich noch nie einen Anwednungsfall für realloc gesehen?



  • Hallo,

    Ich habe es jetzt so gemacht:

    main.c - int main:

    char *buffer;
    
      //...
    
      input = fopen("input.txt","r");
    
      //...
    
      buffer = (char*)malloc(ftell(input));
    
     //...
    
     /* Das geht alles wunderbar, das einlesen der File auch, aber hier kommt immer eine Art Segmentation fault:  */
    
      fclose(input);
      free(buffer);
    
      printf("\n");
      system("PAUSE"); //ab hier	
      return 0;
    

    why? Danke



  • hast du vor dem ftell sowas gemacht?

    fseek (input, 0, SEEK_END);
    

    ausserdem besser im binary mode öffnen: fopen("input.txt","r+b")



  • Hi net,

    habe jetzt:
    fseek(input,0, SEEK_END);
    buffer = (char*)malloc(ftell(input));

    Jetzt spuckt er nur Herzchen aus in der Dos Zeile... super, zuerst geht er nicht, dann ist er in mich verliebt.

    gruss johnny.xy



  • johnny.xy schrieb:

    fseek(input,0, SEEK_END);
    buffer = (char*)malloc(ftell(input));

    vor'm einlesen musste den filepointer wieder auf den anfang setzen. probier mal dies:

    ...
    fseek(input,0, SEEK_END);
    buffer = (char*)malloc(ftell(input));
    fseek(input, 0, SEEK_SET);
    ...
    

    oder als extra funktion um die grösse rauszufinden:

    long file_size (FILE *f);
    {
     long cur_pos, length;
     cur_pos = ftell(f)
     fseek(f, 0, SEEK_END); // set pointer to end of file
     length=ftell(f); // offset in bytes from file's beginning
     fseek(f, cur_pos, SEEK_SET); // restore original position
     return length;
    }
    


  • #include <stdio.h>
    
    int main(int argc, char *argv[]) {
      FILE *input = fopen(argv[1], "r");
      char *text;
      int len;
    
      fseek(input, 0, SEEK_END); /* Ans Ende der Datei gehen (genaugenommen hinter das Ende der Datei) */
      len = ftell(input); /* Momentane Position in der Datei merken, also in diesem Fall die Länge der Datei */
      rewind(input); /* Wieder auf Anfang gehen */
    
      /* Speicher alloziieren - einen mehr als die Länge der Datei für den Sentinel.
       * calloc überschreibt den Speicher mit Null - das ist hier vielleicht etwas
       * verschwenderisch, aber zu Anschauungszwecken OK, und so ist sicher,
       * dass der Sentinel auch \0 ist. Alternativ:
       * 
       * text = (char*) malloc(len + 1);
       * text[len] = '\0';
       */
      text = (char*) calloc(len + 1, sizeof(char));
      fread(text, sizeof(char), len, input); /* Datei einlesen */
    
      printf(text); /* Datei ausgeben */
    
      free(text); /* Speicher freigeben */
      return 0;
    }
    


  • Hi,

    Danke OxDeadBeef. Ist malloc weniger verschwenderisch? Wieso ist es verschwenderisch und was ist "Sentinel"?

    Vielen Dank für eure treue Hilfe.

    johnny.xy

    PS: Um euch herum werd ich ja richtig gut *hehe*



  • Erstmals, sorry für doppelposting! Ist normalerweise nicht meine Art.

    Wieso len + 1 in der calloc? Ich habe es nur mit len probiert, aber ich stelle keinen Unterschied fest.

    Danke



  • Der Sentinel ist das Zeichen, das das Ende des Strings markiert. In C ist das '\0'.

    len + 1 deshalb, weil der String sowohl den Inhalt der Datei als auch den Sentinel fassen muss. Wenns auch mit len geht, war wahrscheinlich ein \0-Zeichen am Ende der Datei.

    calloc braucht in der Tat mehr Rechenzeit als malloc (jedenfalls, wenn die Implementierung nicht völlig bekifft gemacht ist), weil calloc mehr macht als malloc. malloc fordert Speicher an, calloc fordert Speicher an und überschreibt ihn mit Nullen. Da uns in diesem Fall nur interessiert, dass am Ende des Strings eine Null steht, ist calloc eigentlich overkill.



  • HI,

    Nun bin ich ein wenig verwirrt, aber ich versuchs:

    malloc: erstellt Dyn. Speicherbereich
    calloc: erstellt Dyn. Speicherbereich und füllt diesen mit Nullen + Sentinel?
    realloc: verändert den Dyn. Speicherbereich?

    Vielen Dank.

    Gruss, johnny.xy



  • johnny.xy schrieb:

    realloc: verändert den Dyn. Speicherbereich?

    jo, im einfachsten (und langsamsten) fall macht 'realloc' ein weiteres malloc, kopiert die daten aus dem alten speicher da rüber und löscht den alten speicherbereich.



  • Vielen Dank für eure treue Hilfe.

    johnny.xy


Anmelden zum Antworten