An bestimmter Position in Datei Text einfügen bzw. ersetzen
-
Hi Leute,
Bin schon den ganzen Vormittag dran zu versuchen in einer Textdatei einen Wert zu ändern bzw. zu ersetzen. Hab mich schon tot gegoogelt und gelesen aber irgendwie bin ich scheinbar zu doof, oder hab das ganze noch nicht so wirklich gerafft.

Folgendes:
Hab eine Textdatei die folgendermaßen aussieht;
1001 Tastatur_elegant Formschoene_Tastatur_im_edlen_Design a 19 28 20 40 35 001 1002 Monitor_einfach kostenguenstiger_Monitor_fuer_Buerozwecke_optimiert b 80 120 10 30 15 002 1003 Laptop_GamePower Leistungsstarker_Laptop_mit_hochleistungs_Grafikkarte c 1010 1450 5 10 7 001 1004 Maus_easy kleine_handliche_Computermaus c 2 4 30 50 49 003 1005 Netzteil 450Watt_PC-Netzteil b 35 68 10 20 18 003 1006 Monitor_einfach kostenguenstiger_Monitor_fuer_Spiele_optimiert b 75 110 10 30 15 002 1007 Festplatte_HDReady Enorm_Grosse_Festplatte_fuer_viel_Speicherplatz b 69 85 25 50 40 002 1008 Multifunktionsdrucker_Gappa Fuer_Hochaufloesende_Bilder_zum_Kopieren_Scannen c 90 119 6 11 8 002 1009 Wireless_LAN_Router fuer_eine_einzigartige_Kabellose_Verbindung_ins_Internet a 70 99 20 40 35 002 1010 Farblaserdrucker Hohe_Aufloesung_und_extrem_schnellen_Ausdruck_machen_diesen_Drucker_komplett_Buerotauglich b 340 420 5 10 7 001 1011 Laptop_Tasche perfekte_verarbeitung_und_exterm_viel_Platz b 18 25 30 60 40 002 1012 USB_Stick mit_enorm_viel_Platz_fuer_ihre_Sicherung_von_Daten a 20 30 20 30 25 001 1013 Digitalkamera mit_sehr_hoher_Auflösung_und_jede_Menge_Speicherplatz c 60 89 20 35 30 002und meine Funktion welche einen Wert (neuer Lagerbestand) ändern soll
//--------------------------------------------------------------------------- #include <vcl.h> #include <iostream.h> #include <fstream> #include <sstream> #include <vector> #pragma hdrstop #include "funktionen.h" #include "kdbestell.h" #include "Produkt.h" //--------------------------------------------------------------------------- #pragma package(smart_init) void abschliessen(int kunden_nr, vwk_produkte warenkorb[], int max) { . . . //-------------------------------------------------------Prüfen ob Nachbestellt werden muss produkt p; vector<produkt> vecp; ifstream infile_produkt; string datensatz; infile_produkt.open("DB_Produkte.txt"); //--Produkt Textdatei öffnen // if (!infile_kdbestell) return 0; //Abbruch falls datei nicht vorhanden getline(infile_produkt,datensatz); //infile in Datensatz(Struktur) übertragen while (!infile_produkt.eof()) { istringstream input(datensatz); input >> p.id >> p.bez >> p.info >> p.klasse >> p.ek >> p.vk >> p.soll_bestand >> p.normal_bestand >> p.ist_bestand >> p.lieferant; input.clear(); if(warenkorb[j].pid==p.id) { //----------------------------------Anzahl überprüfen p.ist_bestand=9999; //<-------------------------------nur zum testen ofstream outfile_produkt; outfile_produkt.open("DB_Produkte.txt",ios_base::app); // outfile_produkt.seekp() << p.id; outfile_produkt << p.id << " " << p.bez << " " << p.info << " " << p.klasse << " " << p.ek << " " << p.vk << " " << p.soll_bestand << " " << p.normal_bestand << " " << p.ist_bestand << " " << p.lieferant << endl; } vecp.push_back(p); getline(infile_produkt,datensatz); //---neue Anzahl schreiben } if (infile_produkt.is_open()) infile_produkt.close(); infile_produkt.clear(); vecp.clear(); . . . } } cout << "Die Daten wurden im System aufgenommen." << endl; } system("PAUSE"); system ("CLS"); }Hab mir gedacht das ich einfachheitshalber die ganze Zeile überschreibe. Ich schaffe es aber nicht den Cursor in der Datei richtig zu positionieren. Entweder fügt er eine Zeile am Ende an oder aber überschreibt er die ganze Datei und es steht nur noch die neue Zeile darin.
Wie man sieht hab ich es schon mit "seekp" bzw. "seekl" probiert, aber irgendwie ist das glaub ich nicht so ganz das richtige oder ich mache da was falsch.

Hoffe mir kann da jemand helfen. Danke

gruß merc
-
Solange du die Zeilenlängen nicht beeinflußt bei deinen Änderungen, kannst du mit seekp() an die richtige Stelle springen und dort die nötigen Teile überschreiben (die Datei mußt du dazu als 'ios::in|ios::out' öffnen*).
Wenn sich die Zeilenlänge ändern könnte, mußt du alles, was hinter der Einfügeposition steht, umkopieren, um Platz zu schaffen bzw. die Lücken aufzufüllen.
PS: Ich würde es ja so machen, daß ich die Datei einmal komplett in einen (z.B.) vector<produkt> einlese, alle notwendigen Änderungen vornehme und am Ende den kompletten vector zurückschreibe.
* ios::app bewirkt, daß alle Ausgaben hinten an die Datei angehängt werden, unabhängig von der mit seekp() eingestellten Schreibposition, ios::out alleine löscht den bisherigen Dateiinhalt.
-
Hi
Danke für die Hilfe,
das mit dem "seekp()" hat zwar nicht so richtig geklappt und hat für mich nicht ganz nachvollziehbare Fehler verursacht, könnte aber auch an mir liegen
Ist aber nicht weiter schlimm, hab mir nach nem bißchen lesen deinen Tipp mit dem Vektor zu Herzen genommen und schreibe jetzt die Datei jedes mal vollständig neu.
Ich finde es zwar nicht so geeignet die "halbe Datenbank" jedes mal komplett neu schreiben zu müssen, aber wir haben ja schließlich in der Schule die Vorgabe bekommen TXT Dateien verwenden zu müssen.
Ist unsere Lehrerin halt selber schuld :pDanke nochmal
-
Eine Alternative (wenn es dir nicht auf die Reihenfolge der Dateieinträge ankommt) wäre es vielleicht, den alten Eintrag nur als ungültig zu kennzeichnen, wenn der neue nicht mehr in die Zeile passen würde, und am Dateiende einen neuen Eintrag anzuhängen.
(wenn du die z.B. Bestellmenge verkleinerst, wird die Ausgabezeile kürzer und du mußt nur ein Trennzeichen einfügen, um zu markieren, daß der Rest der physichen Zeile "Müll" ist. Wenn die Bestellmenge vergrößert wird und der neue Eintrag nicht mehr in die Zeile (inklusive eventuellen Reserven) passen würde, überschreibst du z.B. die Seriennummer in der Zeile mit 0000 (für "ungültig") und hängst am Dateiende einen neuen Eintrag an.)