problem: textdatei in unsized string array speichern



  • hi folks!

    ich habe ein kleines problem.
    und zwar versuche ich, eine text-datei mit fgetc() byteweise auszulesen und in einen unsized string array zu speichern, je eine zeile.

    also wenn ich es initialisiere und manuell den inhalt definiere geht es:

    char *bla[] = {};
    
    bla[1] = "irdend";
    bla[2] = "ein";
    bla[3] = "text";
    

    mein späterer code sah etwa so aus:

    #include <stdio.h>
    
    int main(int argc, char *argv[]) {
    
        char *bla[] = {};
    
        FILE *infile;
        char ctemp[1];
        int c;
        int linecount = 0;
        int totallines = 0;
    
        infile = fopen("in.txt", "r");
        while(c != EOF) {
          c = fgetc(infile);
          if(c == '\n') {
            linecount++;
            }
          else {
          sprintf(ctemp, "%c", c);
          strcat(bla[linecount], ctemp);
          }
        }
    
        totallines = linecount;
    
        fclose(infile);
        c = 0;
        while(c < totallines) {
        printf("%s\n", bla[c]);
        c++;
        }
    
        return 0;
    }
    

    und der stürzt immer ab, scheint an strcat zu liegen........

    weiss jemand worans liegt?

    ---loki



  • Bitt, int main benutzen.



  • stimmt, habe ich aber nur beim rekonstruieren vergessen. liegt nicht daran 😞



  • Ich weiß, dass es an den int main nicht lag.

    Meine Vermutung ist

    char *bla[] = {};
    

    Du solltest schon eine feste Größe eingeben, am besten

    char** bla;
    

    und mit malloc arbeiten & realloc arbeiten.

    strcat kann auch nur an strings Texte hinzufügen. Das heißt, dass bla[linecount] ein \0 terminierendes String sein soll, und beim ersten Durchlauf ist es nicht.

    Willst du Zeile für Zeile in einem Array speichern?



  • gibt es vielleicht eine bessere art das zu machen?

    also der komplette inhalt der text-datei muss mit fgetc zeilenweise in den speicher gelesen werden und später muss jede einzelne zeile dynamisch abrufbar sein (daher als array).
    später muss ich also z.b. mit arrayname[n] arbeiten können....



  • Willst du unbeding mit fgetc arbeiten? Wieso nicht Zeilenweise mit fgets?



  • muss ich. die datei ist verschlüsselt, und muss beim auslesen noch entschlüsselt werden, was am besten mit fgetc funktioniert.
    weiteres problem: mit malloc und realloc kenne ich mich nicht aus...



  • man: malloc(3)
    man: realloc(3)

    es ist einfach zu benutzen, aber man muss gut aufpassen, dass die Zeiger nicht verloren gehen, sonst hat man am Ende nur Speicherlecks.



  • sh*t, ich kapiere das einfach nicht.
    kann ich nicht einfach zu beginn sagen wir 8 kB speicher deklarieren und dann damit arbeiten?



  • Achtung, hab das so geschrieben, nicht kompiliert, sollte aber funktionieren. Sorry falls irgendwo Syntax-Error. Es ist nicht die beste Lösung, aber sie sollte gehen. Kannst den Code ja anppassen.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main (int argc, char **argv) {
        FILE *fp;
        int c;
        size_t counter = 0;
        char *str = (char*)malloc(sizeof(char)),
             file_path[] = "in.txt";
    
        if ((fp = fopen (file_path, "r")) == NULL) {
            fprintf(stdout, "Fehler beim Oeffnen der Datei %s\n", file_path);
            return 1;
        }
    
        while ((c = fgetc(fp)) != EOF) {
            ++counter;
            str = (char*)realloc(str, sizeof(char) * (counter));
            *(str + counter-1) = c;
        }
        printf("%s", str);
    
        if ( fclose (fp) != 0) {
            fprintf(stdout, "\nFehler beim Schliessen der Datei %s\n", file_path);
            return 1;
        }
        free(str);
        return 0;
    }
    


  • loki1985 schrieb:

    sh*t, ich kapiere das einfach nicht.
    kann ich nicht einfach zu beginn sagen wir 8 kB speicher deklarieren und dann damit arbeiten?

    du kannst, aber wenn du etwas einliest, was größer als 8 KB ist, wirst du Probleme haben.

    Also hier ein Beispiel für mallco und realloc

    /* malloc realloc Beispiel */
    #include <stdio.h>
    #include <stdlib.h>
    
    void print_int_array(const int* arr, size_t len)
    {       
        size_t i;
        printf("{");
        for(i=0; i<len-1; ++i)
          printf("%d, ", arr[i]);
        if (len) printf("%d}\n", arr[len-1]);
    
    }   
    
    int main()
    {   
        int* arr;
        int anzahl=0, neue_anzahl=0, eingabe, i;
    
        printf("Wie viele Zahlen willst du? ");
        scanf("%d", &anzahl);
    
        if (!anzahl  || 0>anzahl)
        {
            fprintf(stderr, "Gib eine Zahl größer 0\n");
            return 1;
        }
    
        /* Speicher reservieren. Ich will "anzhal" neue
           Felder von Typ int, deshalb sizeof(int)*anzahl */
        arr = (int*) malloc(sizeof(int)*anzahl);
    
        if(!arr)
        {
            fprintf(stderr, "Speicher kann nicht reserviert werden");
            return 1;
        }
    
        for(i=0; i<anzahl; ++i)
        {
            printf("%d. Zahl: ", i+1);
            scanf("%d", &eingabe);
            arr[i]=eingabe;
        }
    
        printf("Arr = ");
        print_int_array(arr, anzahl);
    
        printf("Wie viele Zahlen willst du hinzufügen? ");
        scanf("%d", &neue_anzahl);
    
        if (!neue_anzahl  || 0>neue_anzahl)
        {
            fprintf(stderr, "Gib eine Zahl größer 0\n");
            free(arr);
            return 1;
        }
    
        realloc(arr, sizeof(int)*(anzahl+neue_anzahl));
        for(i=0; i<neue_anzahl; ++i)
        {
            printf("%d. Zahl: ", i+anzahl+1);
            scanf("%d", &eingabe);
            arr[i+anzahl]=eingabe;
        }
    
        printf("Arr = ");
        print_int_array(arr, anzahl+neue_anzahl);
    
        /* Speicher wieder freigeben */
        free(arr);
    
        return 0;
    }
    


  • GPC schrieb:

    Achtung, hab das so geschrieben, nicht kompiliert, sollte aber funktionieren. Sorry falls irgendwo Syntax-Error. Es ist nicht die beste Lösung, aber sie sollte gehen. Kannst den Code ja anppassen.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main (int argc, char **argv) {
        FILE *fp;
        int c;
        size_t counter = 0;
        char *str = (char*)malloc(sizeof(char)),
             file_path[] = "in.txt";
    
        if ((fp = fopen (file_path, "r")) == NULL) {
            fprintf(stdout, "Fehler beim Oeffnen der Datei %s\n", file_path);
            return 1;
        }
    
        while ((c = fgetc(fp)) != EOF) {
            ++counter;
            str = (char*)realloc(str, sizeof(char) * (counter));
            *(str + counter-1) = c;
        }
        printf("%s", str);
    
        if ( fclose (fp) != 0) {
            fprintf(stdout, "\nFehler beim Schliessen der Datei %s\n", file_path);
            return 1;
        }
        free(str);
        return 0;
    }
    

    danke. das funktioniert ganz gut. nur kann ich hier (scheinbar) nicht eine einzelne zeile abrufen [printf("%s", str[zeilennummer]);]
    wenn ich das versuche stürzt es ab...

    @supertux: werde mir das mal ansehen. malloc und co scheinen ja öfter gebraucht zu werden.



  • Darauf ist es auch noch nicht ausgelegt, prüf einfach ab ob's ein '\n' ist.



  • Deine str Varible ist auch kein 0-terminierends String!



  • so, habe es endlich geschafft. habe es umgeschrieben dass malloc jedesmal wenn ein neuer array-member beschrieben werden sollte den erstmal auf eine bestimmte speichergrösse bringt.

    thanx für die hilfe!

    ---loki


Anmelden zum Antworten