Datei-Zeilenweise in ein Array lesen



  • Also ich versuche mich etwas genauer auszudrücken:

    Ich möchte ein Programm schreiben in dem ich eine Datei öffnen kann, den Inhalt zeilenweise angezeigt bekomme und die Möglichkeit besitze diese Zeile ganz zu löschen (Datei dann zu aktualisieren) oder die Zeile einfach zu ändern.

    Das Zeilenweise löschen und ändern kann ich momentan nicht realisieren...

    Wie kann man so etwas machen?



  • den richtigen ansatz hast du ja schon, in ein array einlesen.

    am besten kapselst du dir die arbeit es arrays in ein paar funktionen - mittels realloc wird der speicher bei bedarf vergrößert:

    dabei gibts 2 varianten:

    variante a)
    eine zeile darf nie länger als X sein - dann kann man n bisschen was static machen und das vereinfacht die sachen gewaltig
    variante b)
    eine zeile darf beliebig lang sein.
    hierbei würde ich zusätzlich zum array noch jede zeile kapseln, also:

    struct Line
    {
      int length;
      char* buffer;
    };
    
    struct Array
    {
      int count;
      struct Line* lines;
    };
    

    das ganze kann dan (vorausgesetzt du schreibst die nötigen funktionen) so verwendet werden:

    int c;
    struct Array arr;
    InitArray(&arr);
    while((c=fgetc(file))!=EOF)
    {
      if(c=='\n')
        make_newline(&arr);
      else
        push_char(&arr,c);
    }
    

    viel spass 🙂



  • Danke,
    Shade Of Mine

    probier ich gleich aus...
    Sag mal, kennst Du eine Möglichkeit wie ich Zeilenweise rumblättern kann?
    Vorwärts ist ja kein Problem, aber Rückwärts?!!?!

    Ich versuche es zur Zeit mit fsetpos und fgetpos, aber das funktioniert mir nur für einen Datensatz...Ich müßte mir theoretisch doch jedes Zeilende merken, was aber aufgrund der Dateigröße zu einem riesigen Programmieraufwand führt!!!

    Danke 🙂



  • du liest alles ein wie oben beschrieben - dann kannst du über
    arr.Lines[lineNumber]

    auf die Zeile zugreifen.

    noch etwas was mir gerade einfällt:

    ganze datei in den speicher lesen - und mittels strtok dann zerlegen, das wäre uU peformanter.



  • Kannst Du mir deine zweite Variante etwas genauer erklären?

    Ich verstehe nicht ganz :
    InitArray - wie und woher?
    make_newline???
    und
    push_char ???

    Hast Du diese selber geschrieben?

    Danke 😕



  • ne, das war nur ne Idee - DU musst sie selber schreiben.

    aber wenn du alles schön kapselst, dann ist das kein problem:

    beispiel:

    struct Line
    {
      int allocated;
      int used;
      char* buffer;
    };
    
    void InitLine(struct Line* line)
    {
      line->used=0;
      line->allocated=255;
      line->buffer=malloc(255);
    }
    
    void push_char(struct Line* line, char c)
    {
      if(line->used == line->allocated) // alles besetzt
      {
        const char* tmp=realloc(line->buffer,line->allocated+255);
        if(!tmp) { /* fehler */ exit(-1); } //überleg dir ne bessere fehlerbehandlung
        line->buffer=tmp;
        line->allocated+=255;
      }
      line->buffer[++used]=c;
    }
    
    bzw.
    struct Array
    {
      int numLines;
      int allocated;
      struct Lines* lines;
    };
    
    void make_newline(struct Array* arr)
    {
      if(allocated == numLines) // alles voll
      {
        //realloc wie oben
      }
      ++numLines;
    }
    

    usw.

    wenn du das so machst dann sollte die aufgabe nicht unschaffbar sein.

    am besten du überlegst dir was du brauchst und legst nur mal die prototypen an, und dann gehts erst ans implementieren (dabei helfe ich dir natürlich gerne)



  • Jo, bekomme beim Compilieren
    Fehlermeldungen!!!

    void InitLine(struct Line* line)
    {
        line->used=0;
        line->allocated=255;
        line->buffer=malloc(255);//cannot convert void* to char*
    }
    

    und noch ein paar ähnliche



  • dann kompilierst du im C++ Modus (oder dein compiler ist n ziemlicher käse)

    wenn du C++ willst, dann gibts wesentlich einfachere möglichkeiten...



  • So habe noch ein bissl herumgetüftelt:
    Die einzelnen Zeichen werden mir nun angezeigt, aber wie bekomme ich die einzelne Zeile???

    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    #include <ctype.h>
    #include <iostream.h>
    #include <process.h>
    #include <stdlib.h>
    
    #define MAX_LINE (2000)
    
    void InitLine(struct Line* line);
    void push_char(struct Line* line, char c);
    void make_newline(struct Array* arr);   
    
    struct Line
    {
        int allocated;
        int used;
        char* buffer;
    };
    
    struct Array
    {
        int numLines;
        int allocated;
        struct Lines* lines;
    };
    
    void main(void)
    {
        FILE *stream;
        //DATEI OEFFNEN
        if ((stream = fopen("SAVE.DAT","rw+t")) == NULL)
        {
            printf ("\nFehler beim Oeffnen der Datei!");
            exit(1);
        }
        fseek(stream,0,SEEK_SET);
        long i=0,c;
        //Objektbildung
        struct Array arr;
        struct Line line;
    
        InitLine(&line);
    
        while((c=fgetc(stream))!=EOF)
        {
            if(c=='\n')
            {
                make_newline(&arr);
                ++i;
            }
            else
            {
                push_char(&line,c);
                printf("\n%ld<->%c",i,c);
            }
    //      getch();
        }
        printf("\n%ld Lines",arr); //NICHT RICHTIG,oder???!!?!
        getch();
    
    }
    
    void InitLine(struct Line* line)
    {
        line->used=0;
        line->allocated=255;
        line->buffer=(char *)malloc(255);
    }
    
    //push_char
    void push_char(struct Line* line, char c)
    {
        if(line->used == line->allocated) // alles besetzt
        {
            const char* tmp=(char *)realloc(line->buffer,line->allocated+255);
            if(!tmp)
            {   // fehler
                exit(-1);
            } //überleg dir ne bessere fehlerbehandlung
            line->buffer=(char*) tmp;
            line->allocated+=255;
        }
        int used=line->used;
        line->buffer[++used]=c;
    }
    
    //make_newline
    void make_newline(struct Array* arr)
    {
        if(arr->allocated == arr->numLines) // alles voll
        {
            //realloc wie oben
        }
        int numLines=arr->numLines;
        arr->numLines=++numLines;
    }
    

    🙄



  • Moin,

    oh das wär nicht schlecht...ja ich kompiliere in Borland C++ 3.0. Dachte mir im ANSI C Forum gibt es mehr hilfreiche Lösungen und bessere Poster... 😉

    Hast Du denn einen Vorschlag für mich?

    Dankeschön... @SOM



  • sieh, das Einfache liegt so nah

    #include  <stdio.h>
    #include  <stdlib.h>
    
    #define MAX_ZEILLAENG   200
    
    int  main(int argc, char *argv[])
    {
       FILE    *fz;
       char    zeile[MAX_ZEILLAENG];
       int     zeilnr=0;
       int     nummer;
       char    dateiname[50];
       printf("Welche Datei soll gelesen werden ?\n");
       scanf("%s",dateiname);
       printf("Welche Zeile soll gelesen werden ? ");
       scanf("%d",&nummer);
       fz=fopen(dateiname,"r");
       while (zeilnr<nummer)
       {
          fgets(zeile, MAX_ZEILLAENG, fz);
          zeilnr++;
       }
         fprintf(stdout, "%5d  %s", zeilnr, zeile);
    
       if (ferror(fz)) {
          fprintf(stderr, "....Fehler beim Lesen aus Datei `%s'", argv[1]);
          exit(3);
       }
       fclose(fz);
       system("pause");
       return(0);
    }
    

    mfg
    pierre



  • JO,Piere

    läuft...super...

    ich habe da noch eine bitte. Kennst Du eine Möglichkeit wie ich in den einzelnen Zeilen, je nach Tasteneingabe, bewegen und einzelne Zeilen editieren bzw löschen kann?

    SORRY, dass ich mich jetzt erst melde...hatte in letzter Zeit viel zu tun.

    DANKE an alle...



  • Hi,

    indem du die einzelnen Zeilen z.B. in einem Array z.B. von char-Pointers
    sammelst und dann die Tasten(kombinationen) als char bzw. char-Pointer abfragst.

    Mfg
    pierre


Anmelden zum Antworten