C Datei Edit ("suchen und ersetzen")



  • Hi, vorab ich hab schon 2-3 Bücher über Dateien in C gelesen und bin noch nicht wirklich fündig geworden.

    Ich suche eine Möglichkeit um eine spezielle spalte in einer Datei zu ändern.
    Ohne das der komplette Inhalt verloren geht.

    On binär oder txt ist mir vorerst egal.
    Mit einer Struktur oder Zeichen ebenfalls egal.

    Z.b die Tabelle
    Id Preis
    aa 20
    bb 40
    cc 60

    Hier möchte ich die 40 beispielsweise in 80 ändern und die Datei speichern.

    Hat jemand hierfür eine Idee?

    Vielen Dank schonmal.



  • Wenn du keine Daten zufügst² geht das.
    Mit dem Modus "r+" beim fopen kannst du eine Datei zum lesen und schreiben öffnen.
    Du musst dabei mit fseek und/oder fflush arbeiten

    fopen schrieb:

    For files open for update (those which include a "+" sign), on which both input and output operations are allowed, the stream shall be flushed (fflush) or repositioned (fseek, fsetpos, rewind) before a reading operation that follows a writing operation. The stream shall be repositioned (fseek, fsetpos, rewind) before a writing operation that follows a reading operation (whenever that operation did not reach the end-of-file).

    Aus: http://www.cplusplus.com/reference/cstdio/fopen/

    ²Wenn sich die Länge der Datei nicht ändert

    Sonst bleibt nur der Umweg über eine temporäre Datei.
    (Originaldatei zum lesen öffnen, Temp. Datei zum schreiben öffnen, Daten kopieren/ändern, Dateien schließen, orig Datei löschen. temp Datei umbennen)
    Die ist eigentlich der sicherer Weg. Falls etwas beim kopeieren schief geht, bleibt das Original erhalten.



  • - Originaldatei in dynamischen Speicher einlesen
    - dann im Speicher Änderung vornehmen
    - Originaldatei damit wieder überschreiben (komplett!)



  • erstmal vielen dank hat mich schonmal ein gutes stück weiter gebracht, ich hab nicht gewusst das die Dateilänge bzw beim überschreiben gleich sein muss.

    Zur Wutz

    Hast du da ein Code Beispiel für mich, ich wüsste gerade nicht wie ich die tmp speichere bzw den tmp auslese und ihn verändere, vlt brauch man es ja noch später nochmal

    Danke Sehr.



  • jertiri schrieb:

    ich hab nicht gewusst das die Dateilänge bzw beim überschreiben gleich sein muss.

    Du kannst Daten anhängen, aber nicht einfügen.
    Die vorhandenen Daten werden überschrieben.

    jertiri schrieb:

    Zur Wutz

    Hast du da ein Code Beispiel für mich, ich wüsste gerade nicht wie ich die tmp speichere bzw den tmp auslese und ihn verändere, vlt brauch man es ja noch später nochmal

    Was meinst du mit tmp?
    Wutz hat davon nichts geschrieben.



  • ich meine eig

    - Originaldatei in dynamischen Speicher einlesen
    - dann im Speicher Änderung vornehmen
    - Originaldatei damit wieder überschreiben

    Punkt 1+2 meine ich wie man das im C Code realisieren kann,

    Zum oberen ist ja perfekt ich will ja eig nur überschreiben,bzw werte ändern.
    Ich habe auch überlegt alle Paare mit Semikolons zu trennen und die denn suchen um so die position zu bestimmen,



  • jertiri schrieb:

    ich meine eig

    - Originaldatei in dynamischen Speicher einlesen
    - dann im Speicher Änderung vornehmen
    - Originaldatei damit wieder überschreiben

    Punkt 1+2 meine ich wie man das im C Code realisieren kann,

    1. fopen( ,"rb"); fseek( ,0,SEEK_END); ftell; rewind; malloc; fread; fclose
      Zum Nachlesen: http://www.cplusplus.com/reference/cstdio/fseek/
      fseek setzt den Dateizeiger ans Ende der Datei
      Mit ftell bekommst du die Position davon. Du hast jetzt die Dateigröße.
      ftell (aus dem Standard) funktioniert nur bis zu einer Dateigröße von 2 GB.
      Mit der Information kannst du mit malloc genug Speicher anfordern
      Es liefert dir die Anfangsadresse von Speicher.
      Mit rewind kommst du wieder an den Dateianfang
      Und mit fread kannst du die ganze Datei in den Speicher (von malloc ) einlesen.

    2. Auf den Speicher von malloc kannst du wie auf ein Array zugreifen.
      Du musst halt deine Position ermitteln, an der du die Daten ändern willst.

    3. fopen( , "wb); fwrite; fclose; free;
      Das free am Ende nicht vergessen.

    jertiri schrieb:

    Zum oberen ist ja perfekt ich will ja eig nur überschreiben,bzw werte ändern.
    Ich habe auch überlegt alle Paare mit Semikolons zu trennen und die denn suchen um so die position zu bestimmen,

    Du kannst (in einer Textdatei) aber nicht von 99 auf 100 ändern (es sei denn, vor oder hinter der 99 ist genug Platz).



  • super danke euch allen schonmal wird nacher gleich mal ausprobiert 🙂


  • Mod

    DirkB schrieb:

    ftell (aus dem Standard) funktioniert nur bis zu einer Dateigröße von 2 GB.

    Aber nur auf komischen, alten DOS-Extendern. Richtige Plattformen haben keine solche Probleme 😉



  • okay mein code schaut erstmal so aus , nicht schön ich weiß und auch keine Errors abgefangen

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    
    void main()
    {
    	FILE* file;
    	file = fopen("va2.txt", "rb");
    	int i;
    	int test[10];
    	int *p = (int*)malloc(10 * sizeof(int));
    	p[2] = 40;
    
    	fseek(file, 0, SEEK_END); 
    	i = ftell(file);
    	rewind(file); 
    
    	malloc(i);
    	fread(&test, sizeof(int), 10, file);
    	printf("Wert %d | Test2= %d\n", i, test[1]);
    	fclose(file);
    
    	fopen(file, "wb");
    	//fwrite;
    	fclose(file);
    	free; (i);
    
    	system("PAUSE");
    }
    

    vr2.txt sind einfach mal nur ein paar zahlen

    Wie bekomme ich den die Adresse von Malloc also wo der res. Speicher anfängt und wie nutze ich diese Adresse in fread,

    Danke schonmal



  • So much wrong.

    Wenn meine Tochter nicht heute Geburtstag hätte würde ich en detail drauf eingehen. Keine Zeit.

    Leute die es nicht mal schaffen "Code markieren + C" auszuführen sind sowieso nicht auf meiner most important list,



  • 1. Schmeiss den Testkram raus.
    2. Halte Dich an die Reihenfolge, die Dir DirkB gegeben hat.
    3. Du benutzt malloc hier

    int *p = (int*)malloc(10 * sizeof(int));
    

    doch schon fast richtig (schmeiss den cast weg...) warum kannst Du das denn bitte hier

    malloc(i);
    

    nicht?



  • jertiri schrieb:

    vr2.txt sind einfach mal nur ein paar zahlen

    .txt deutet auf menschenlesbar hin (da mit einem Texteditor erstellt).
    Dann sollte p aber ein char* und du solltest noch (mindestens) ein Byte mehr von malloc anfordern und dieses letzte Byte auf '\0' setzten.
    (oder gleich calloc nehmen)
    Dann kannst du mit puts(p); den Text ausgeben.


Anmelden zum Antworten