Ich versuche, eine Datei für die Ausgabe zu öffnen und an sie anzuhängen. Nach dem Anhängen möchte ich meine Ausgabeposition an anderer Stelle in der Datei verschieben und existierende Daten überschreiben. Wie ich es verstehe, std::ios_base::app
wird force schreibt alles am Ende der Datei, die ist nicht was ich tun möchte. Als solches glaube ich, std::ios_base::ate
ist das richtige Flag, um an std::ofstream::open()
zu übergeben. Allerdings scheint es, wird nicht wie erwartet funktioniert:Std :: Ofstream mit Std :: ate nicht am Ende öffnen
// g++ test.cpp
// clang++ test.cpp
// with and without -std=c++11
#include <iostream>
#include <fstream>
int main() {
std::streampos fin, at;
{
std::ofstream initial;
initial.open("test", std::ios_base::out | std::ios_base::binary);
if (not initial.good()) {
std::cerr << "initial bad open" << std::endl;
return 1;
}
int b = 100;
initial.write((char*)&b, sizeof(b));
initial.flush();
if (not initial.good()) {
std::cerr << "initial write bad" << std::endl;
return 1;
}
fin = initial.tellp();
}
{
std::ofstream check;
check.open("test", std::ios_base::out | std::ios_base::binary | std::ios_base::ate);
if (not check.good()) {
std::cerr << "check bad open" << std::endl;
return 1;
}
at = check.tellp();
if (fin != at) {
std::cerr << "opened at wrong position!\nfin:\t" << fin << "\n" << "at:\t" << at << std::endl;
return 1;
}
int bb = 200;
check.write((char*)&bb, sizeof(bb));
check.flush();
if (not check.good()) {
std::cerr << "check write bad" << std::endl;
return 1;
}
at = check.tellp();
}
if ((fin + std::streampos(sizeof(int))) != at) {
std::cerr << "overwrite?\nfin:\t" << fin << "\n" << "at:\t" << at << std::endl;
return 1;
}
return 0;
}
Insbesondere scheint es, dass std::ios_base::ate
tut nicht bewegen die anfänglichen Ausgabezeiger auf das Ende mit dem Beispiel oben gesehen. Offensichtlich würde dies dazu führen, dass der erste Schreibvorgang den Anfang der Datei überschreibt (was meine Probleme verursacht hat).
Es scheint, dass entweder die Umsetzung nicht korrekt ist oder sonst cplusplus.com ist falsch („Die Ausgangsposition am Ende der Datei beginnt.“) und cppreference.com ist nicht eindeutig („bis zum Ende des Stromes suchen Sie sofort nach offen ": welcher Stream?".
Es gibt natürlich eine einfache Abhilfe: Verwenden Sie einfach stream.seekp(0, std::ios_base::end)
.
Also meine Frage ist also: ist mein Code falsch? Ist die Implementierung falsch? Sind die Referenzstellen falsch? Jeder Einblick würde geschätzt werden.
http://en.cppreference.com/w/cpp/io/ verkürzt werden basic_filebuf/öffnen. Verwenden von "out" ohne "app" oder "in" schneidet ab. –