PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++] Datei öffnen, eine Stelle ändern und Datei speichern&schließen


Gast
2011-07-08, 15:41:42
Hallo ihr,

ich bin grad glaub ich einfach zu blöd:


std::string buf;
std::string line;
std::ifstream in("datei.txt");

while(std::getline(in,line))
buf += line;

size_t blubb = buf.find("12 34");

buf[blubb+4] = '0';
buf[blubb+5] = 'e';


Damit lese ich eine Datei ein und suche nach "12 34". In "blubb" steht dann die Position der "1". Nun ändere ich ausgehend von blubb "34" in "0e" um und möchte die Änderung wieder in die Datei schreiben.
Wie zum Henker erledige ich den letzten Schritt? :)

Marscel
2011-07-08, 16:12:44
Du verwendest einen Input Filestream (ifstream), damit kannst du gar nichts schreiben. Was du brauchst, das ist ein fstream (http://www.cplusplus.com/reference/iostream/fstream/fstream/), mit in und out, dann hat dein Fileobjekt Lese- und Schreibemethoden.

Gast
2011-07-08, 16:24:43
Ups...hab ich nun geändert aber es gibt immer noch die gleichen Methoden.
Wie kann ich nun in der eingelesenen Datei einen Wert an einer bestimmten Stelle ändern?

Marscel
2011-07-08, 16:36:55
Da du ja sowieso den gesamten Dateiinhalt in den buf einließt, schreibst du ihn danach einfach zurück, irgendwie sowas:

in.seekg(0);
in.write(buf.c_str(), buf.length());
in.close();

Schau dir ruhig die Dokumentation an, da steht mit Beispielen alles, was du brauchst.

Gast
2011-07-08, 16:38:25
Die "write"-Methode wird bei mir nicht aufgelistet...zefix, irgendwas überseh ich bestimmt :).

Marscel
2011-07-08, 16:44:11
Hast du

#include <fstream>

vor der Passage stehen? Wenn da nur <ifstream> ist, ersetzen.

Gast
2011-07-08, 16:45:42
Hab ich drin, ändert leider nichts.

Marscel
2011-07-08, 16:51:17
Was heißt aufgelistet. Wenn dir deine IDE beim Tippen die Objektmethoden anzeigt und da kein write() auftaucht, ist das egal. Wenn der Compiler streikt, dann wirds interessant.

So ugf sollte es aussehen, kompilieren und auch funktionieren.

#include <fstream>

// ...

std::string buf;
std::string line;
std::fstream in("datei.txt", std::fstream::in | std::fstream::out);

while(std::getline(in,line))
buf += line;

size_t blubb = buf.find("12 34");

buf[blubb+4] = '0';
buf[blubb+5] = 'e';

in.seekg(0);
in.write(buf.c_str(), buf.length());
in.close();

Gast
2011-07-08, 18:03:33
Stimmt, geht tatsächlich obwohl die Autovervollständigung "write" nicht kennt. Danke! :D

Gast
2011-07-09, 13:34:06
Ich vermute, du musst das Projekt/Datei neu builden damit er auch die neuen Includes kennt.

wori
2011-07-18, 13:32:31
Besorg Dir ein Lehrbuch/Tutorial.
Da sind solche Basics beschrieben und bebildert.

Gast
2012-03-28, 09:44:11
Was heißt aufgelistet. Wenn dir deine IDE beim Tippen die Objektmethoden anzeigt und da kein write() auftaucht, ist das egal. Wenn der Compiler streikt, dann wirds interessant.

So ugf sollte es aussehen, kompilieren und auch funktionieren.

#include <fstream>

// ...

std::string buf;
std::string line;
std::fstream in("datei.txt", std::fstream::in | std::fstream::out);

while(std::getline(in,line))
buf += line;

size_t blubb = buf.find("12 34");

buf[blubb+4] = '0';
buf[blubb+5] = 'e';

in.seekg(0);
in.write(buf.c_str(), buf.length());
in.close();


Die Lösung von Marscel klappt schon irgendwie, allerdings gibt es hier 2 Probleme:

1. Zeilenumbrüche werden vermutlich schon beim Lesen verworfen, d.h. beim Schreiben steht alles hintereinander, ohne Zeilenumbrüche.

2. Die eingelesene Datei wird nicht überschrieben, sondern der gesamte Buffer wird am Dateiende eingefügt (zusammenhängend ohne Zeilenumbrüche), so dass der gleiche Dateiinhalt - mit dem ersetzten Teil - nochmal in der Datei steht.

Wie kann man die Probleme lösen?

Coda
2012-03-28, 10:28:06
Meta-Diskussion: Warum sollte man sowas in C++ machen wollen? Übung?

mekakic
2012-03-28, 10:44:11
Muß man denn die ganze Datei in den Buffer einlesen? Die kann doch auch arg groß werden. Warum nicht direkt beim Einlesen gucken wonach man sucht und rechtzeitig aufhören?

ShadowXX
2012-03-28, 10:46:24
1. Zeilenumbrüche werden vermutlich schon beim Lesen verworfen, d.h. beim Schreiben steht alles hintereinander, ohne Zeilenumbrüche.

Ja, das liegt am 'getline(...)', du musst 'get(...)' oder 'read(...)' benutzen. Kann sein das du das ganze sogar eher Binär einlesen musst.

Die beiden funktionieren aber etwas anders als das getline, am besten mal hier ein Blick drauf werfen: http://www.cplusplus.com/reference/iostream/fstream/


2. Die eingelesene Datei wird nicht überschrieben, sondern der gesamte Buffer wird am Dateiende eingefügt (zusammenhängend ohne Zeilenumbrüche), so dass der gleiche Dateiinhalt - mit dem ersetzten Teil - nochmal in der Datei steht.

Das dürfte daran liegen das mit 'seekg()' nur der get-pointer der Datei geändert wird, aber nicht der Schreib-pointer....einfach mal oben in die referenz gucken.


Muß man denn die ganze Datei in den Buffer einlesen? Die kann doch auch arg groß werden. Warum nicht direkt beim Einlesen gucken wonach man sucht und rechtzeitig aufhören?
Das wäre sowieso die wesentlich bessere lösung.

Gast
2012-03-28, 13:36:46
Meta-Diskussion: Warum sollte man sowas in C++ machen wollen? Übung?

Wie würdest du es denn anstellen?

Gast
2012-03-28, 16:59:40
Wie würdest du es denn anstellen?

sed -i "s/12 34/12 0e/g" datei.txt

oder ähnliches in Perl oder einer ähnlichen Spache. Aber aufpassen: Das Beispiel oben ersetzt alle Stellen mit "12 34".

Coda
2012-03-29, 00:13:55
Wie würdest du es denn anstellen?
Python, Perl, Ruby, Bash, sed, awk

Such dir was aus. Alles besser dafür geeignet als C++.