Datei in Unterordner zum schreiben öffnen
-
Hallo zusammen,
ich möchte eine Datei in einem Unterordner zum schreiben öffnen und falls sie nicht existiert neu anlegen und falls der Unterordner nicht exisitert, soll er auch angelegt werden.
Ich hab das dann ganz einfach versucht:
(Hab den code eine bischen abgeändert, gekürzt und QT-Zeugs rausgenommen)void SerialPortWorker::startRecord(std::string filePrefix) { std::string fileName = filePrefix + getTimeString() + ".csv"; outputFile_ = new std::ofstream(fileName.c_str()); if(!(*outputFile_)) { showError("Failed to open file"); delete outputFile_; outputFile_ = 0; } }
Leider wird der block vom if angesprungen und showError ausgelöst...
Der FileName war in diesem Fall:
".\erste_Tests\Daniel_2011-07-22-11-02-51.csv"(Ich hab das sowohl mit .\ als auch ohne getestet, beides mal hats nicht geklappt.
Was mache ich falsch, wie gehts richtig?
-
Nimm mal / statt \
Und ostreams mit new anlegen? Gibt's dafür einen (guten!) Grund?
-
Mit / funktionierts leider auch nicht
Das mit new benutz ich eigentlich nur damit ich wenn es 0 ist weiß das keine datei offen ist und ansonsten schon, ich weiß, das geht auch mit isOpen oder sowas, aber ich denke nicht, dass das hier das problem ist.Hat sonst noch jemand ideen, warum das nicht funktioniert?
Edit:
hab mal nochmal nen paar Sachen getestet (leider schlägt alles fehl...):#include <fstream> #include <iostream> using namespace std; int main() { fstream f(".\\unterordner\test.txt"); if(!f) { cerr << "failed to open first file!" << endl; } fstream f2(".\\unterordner\test.txt"); if(!f2) { cerr << "failed to open second file!" << endl; } fstream f3("unterordner\test.txt"); if(!f3) { cerr << "failed to open third file!" << endl; } cin.peek(); return 0; }
Ausgabe:
failed to open first file!
failed to open second file!
failed to open third file!
-
Q schrieb:
und falls der Unterordner nicht exisitert, soll er auch angelegt werden.
Finde die Funktion, die Ordner anlegen kann und rufe sie vorher auf.
-
gibts da ne standard-funktion?
Wenn ja, wärst du so freundlich mir den namen zu verraten?
Hab auf die schnelle mit googlen nur sachen wie
mkdir gefunden, die afaik platformabhängig sind.Und was passiert, falls der Unterordner doch schon da war, wird er dann überschrieben?
Edit: Hab was von Qt gefunden, dann nehm ich das, sofern es wirklich nichts vom standard gibt.
-
Also habe noch nie gesehen, dass man einen ofstream mit new anlegt...
gibt doch genug funktionen, die überprüfen, was du willst: is_open(), open(), close(), fail() bzw good()void I_Open_A_File(std::string filename) { std::string dir = "\\Unterordner1\\Unterordner2\\"; fstream file((dir+filename).c_str()); if(file.fail) { cerr << Could not open file: " << filename << " in folder: " << dir << endl; return; } /*...*/
Ungetestet, aber bin mir relativ sicher, dass es so funktioniert, da ich es schon einige mal so benutzt habe
-
Q schrieb:
hab mal nochmal nen paar Sachen getestet (leider schlägt alles fehl...):
fstream f(".\\unterordner\test.txt"); if(!f) { cerr << "failed to open first file!" << endl; }
'\' ist ein Zeichen, '\t' ist auch noch eine gültige Escapesequenz (Tabulator) ansonsten hätte der Compiler warnen können.
".\\unterordner**\**test.txt" sollte funktionieren.
-
Ich benutze den File als membervariable, und dazu muss ich wissen, ob gerade eine Messung läuft oder nicht.
Ich hab mir dann einfach gedacht wenn das auf 0 steht läuft keine messung, ansonsten schon.
Ich sehs auch ein, dass die Lösung nicht gut ist, aber eigentlich gehts ja um was anderes.
Deine Funktion hab ich gerade getestet (musste Kleinigkeiten ändern, damits kompiliert).#include <fstream> #include <iostream> #include <string> using namespace std; void I_Open_A_File(std::string filename) { std::string dir = "\\Unterordner1\\Unterordner2\\"; fstream file((dir+filename).c_str()); if(file.fail()) { cerr << "Could not open file: " << filename << " in folder: " << dir << endl; } } int main() { fstream f(".\\unterordner\\test.txt"); if(!f) { cerr << "failed to open first file!" << endl; } fstream f2(".\\unterordner\\test.txt"); if(!f2) { cerr << "failed to open second file!" << endl; } fstream f3("unterordner\\test.txt"); if(!f3) { cerr << "failed to open third file!" << endl; } I_Open_A_File("test.txt"); cin.peek(); return 0; }
Output:
failed to open first file!
failed to open second file!
failed to open third file!
Could not open file: test.txt in folder: \Unterordner1\Unterordner2\Funktioniert also leider auch nicht.
Habs inzuwischen übrigens mit Qt gelöst bekommen, mich würde aber trotzdem interessieren, wie mans mitm standard hinbekommt.
Edit: @yahendrik : danke für den hinweis, habs geändert, macht aber keinen unterschied.
-
Das mit new benutz ich eigentlich nur damit ich wenn es 0 ist weiß das keine datei offen ist und ansonsten schon, ich weiß, das geht auch mit isOpen oder sowas, aber ich denke nicht, dass das hier das problem ist.
Ist ja doppelt falsch.
Den Stream kannst Du wie Du schon gezeigt hast einfach ins if Statement packen. Dann weisst Du obs ging oder nicht.
std::ifstream ifs("test.txt"); if (ifs) { // ifs ist offen und bereit zum lesen } else { // ifs is nicht offen und etwas ging schief! }
Ausserdem ist deine Logik mit dem 0 falsch:
Zuerst legst Du mit new den Stream an - der Zeiger darauf ist entweder gültig oder es wird eine std::bad_alloc Exception geworfen (wenn, salop gesagt, kein Speicher mehr vorhanden ist) - 0 wird der Zeiger so nicht.Ausserdem dereferenzierst Du den Zeiger ja anschliessend, falls der wirklich 0 sein könnte gibts da eine Access Violation!
-
Ihr guckt auch alle nur auf diese eine Methode.
Wie ich bereits sagte ist es eine membervariable.
In der genannten Methode wird der File erstellt.
In anderen Methoden wird überprüft, ob eine Messung läuft (vergleich auf 0).Den Fall, dass new einen 0 pointer zurückgibt, oder eine exception auslöst habe ich gar nicht beachtet, weil ich die annahme treffe, dass das nie passieren wird
void SerialPortWorker::onReadyRead() { //... if(outputFile_) { *outputFile_ << fileTime_ << ',' << kanal1 << ',' << kanal2 << ',' << kanal3 << ',' //... } //... }
//messung beenden delete outputFile_; outputFile_ = 0;
-
Mehr davon!
-
Ich würde mal Vorschlagen:
Back to topic:
Warum klappt das öffnen im Unterordner nicht und wie ist das mit dem Standard möglich?Edit: @volkard: Wie war das gemeint?
-
Warum klappt das öffnen im Unterordner nicht und wie ist das mit dem Standard möglich?
Das klappt garantiert, wenn Du den korrekten Pfad angibst.
Du könntest mal versuchen absolute Pfade anzugeben.
Oder das aktuelle Arbeitsverzeichnis im Debugger setzen - so ist es bekannt.
Oder es einfach mal ausgeben... (unter Windows mit GetCurrentDirectory(..) http://msdn.microsoft.com/en-us/library/aa364934(v=vs.85).aspx).
-
Q schrieb:
Warum klappt das öffnen im Unterordner nicht und wie ist das mit dem Standard möglich?
Das klappt, wenn der Unterordner existiert. '/' ist ok, kein Grund für '\'. Bei relativen Pfaden mußt Du noch wissen, daß aus der IDE heraus das Projektverzeichnis das aktuelle Verzeichnis ist, aber bei Start der Exe mit Doppelklick ist es das Benutzerverzeichnis.
Mir will keine Standard-Funktion einfallen, die Verzeichnisse anlegt. Wenn Du eh Qt mitlaufen hast, ist das doch eine gute Lösung. Ansonsten einen Inline-Wrapper mit #ifdef um CreateDirectory/mkdir.
Q schrieb:
@volkard: Wie war das gemeint?
Die Begründung, den Zeiger zu überladen mit der weiteren Bedeutung, daß eine Messung läuft, zu diesem Zweck auf RAII zu verzichten, dann noch überstürzt mit der Ansage, daß schon kein Fehler passiert, das hat meine Ernsthaftlichkeit für die nächsten Stunden kaputtmacht. Das wird ein guter Tag.