fstream Pfade angeben



  • Hallo Leute
    ich möchte mit einem C++ Programm eine Textdatei mit dem Inhalt "Hallo" erstellen.
    Diese soll allerdings in einem anderen Ordner (C:\Users\JanK411\Documents\) erstellt werden.

    Mein Code hierfür sieht folgendermaßen aus:

    f.open("C:\\Users\\JanK411\\Documents\\test.txt", ios::out);
    f << "Hallo";
    f.close();
    

    Da öffnet sich die Eingabeaufforderung nur kurz und schließt sich wieder.
    es wird aber keine "test.txt" erstellt.

    Wenn ich jedoch den Pfad weg lasse, wird die Datei einfach im selben Ordner wie die exe erstellt, was ja verständlich ist... 😉

    Bin für jede Hilfe dankbar
    MfG JanK411



  • Also wenn du dich nicht in den Ordnernamen geirrt hast und Zugriffsberechtigung für den ordner hast, sollte es Funktioniern.

    Hab grade auch gestestet.

    #include <iostream>
    #include <fstream>
    
    int main(int argc, char* argv[])
    {
        std::fstream filestream;
    
        filestream.open("C:\\Testordner\\Hallotest.txt", std::fstream::out | std::fstream::trunc);
        if(filestream.is_open())
        {
            filestream << "hallo das ist ein test" << std::endl;
            filestream.close();
        }
        filestream.~basic_fstream();
    
        return 0;
    }
    


  • Auf Vista/7 hast du auf C keine Schreibrechte als normaler User.
    PS:

    int main()
    {
      std::ofstream f("test.txt"); // Im Konstruktor öffnen. ofstream braucht kein explizites ios::out
      f << "Hallo, Datei!\n";
    } // Destruktor schließt Datei wieder. Kein close() nötig.
    

    Edit:

    Videonauth schrieb:

    filestream.~basic_fstream();
    

    Autsch. 😮



  • cooky451 schrieb:

    Videonauth schrieb:

    filestream.~basic_fstream();
    

    Autsch. 😮

    Wieso autsch ? 😃
    Sorry manche Gewohnheiten legt man nicht so schnell wieder ab wie man sie sich angewöhnt hat hehehe.



  • Videonauth schrieb:

    cooky451 schrieb:

    Videonauth schrieb:

    filestream.~basic_fstream();
    

    Autsch. 😮

    Wieso autsch ? 😃
    Sorry manche Gewohnheiten legt man nicht so schnell wieder ab wie man sie sich angewöhnt hat hehehe.

    Question: Should I explicitly call a destructor on a local variable?

    Answer: No! The destructor will get called again at the close } of the block in which the local was created. This is a guarantee of the language; it happens automagically; there's no way to stop it from happening. But you can get really bad results from calling a destructor on the same object a second time! Bang! You're dead!



  • Videonauth schrieb:

    Wieso autsch ? 😃

    Da fragst du noch? Du rufst manuell den Destruktor auf!

    #include <iostream>
    
    struct my
    {
      ~my() { std::cout << "destructor\n"; }
    };
    
    int main()
    {
      my s;
      s.~my();
    }
    

    Ausgabe:

    destructor
    destructor
    

    Man verlässt sich aber darauf, dass der Destruktor nur genau ein Mal aufgerufen wird. Was denkst du also passiert, wenn man im Destruktor ein delete aufruft? Genau, dann wird der Speicher gleich zwei mal freigegeben. Und das ist nur eine von einer ganzen Reihe an bösen Überraschungen, die man so bekommen kann. Also merken: nie, nie, nie, unter keinen Umständen den Destruktor manuell aufrufen. Da hast du dir nicht mehr das Bein abgeschossen, da ist auch gleich der Kopf weg.

    Das schmerzt beim Lesen ja mehr als uninitialisierte Pointer dereferenziert zu sehen.



  • Vielen Dank schon mal für die Antworten...
    aber ich entschuldige mich jetzt schon mal für meine folgende dumme Frage:
    was ist ein Constructor/Destructor??
    😛



  • Ok wieder was gelernt. Naja ka hab mir das irgendwann mal angewöhnt alles was ich nicht mehr brauche selber freizugeben, Linden Scripting Language zwingt einen förmlich dazu.



  • JanK411 schrieb:

    was ist ein Constructor/Destructor??

    Google.



  • JanK411 schrieb:

    was ist ein Constructor/Destructor??
    😛

    Ein Konstruktor wird aufgerufen, wenn das Objekt erzeugt wird:

    class MyClass
    {
    public:
       // Standardkonstruktor ohne Eingabe und Initialisierungliste
       MyClass() : m_variable(0)
       {
       }
    
       // Konstruktor mit Eingabe
       MyClass(int variable) : m_variable(variable)
       {
       }
    
    private:
       int m_variable;
    };
    

    Ein Destruktor wird aufgerufen, wenn der Objekt aus dem Scope läuft und zerstört wird oder delete auf das Objekt angewendet wird:

    class MyClass
    {
    public:
       // Standardkonstruktor ohne Eingabe und Initialisierungliste
       MyClass() : m_variable(0)
       {
       }
    
       // Konstruktor mit Eingabe
       MyClass(int variable) : m_variable(variable)
       {
       }
    
       // Destruktor, hier ist aber in dem Beispiel nichts zu tun.
       virtual ~MyClass()
       {
       }
    
    private:
       int m_variable;
    };
    

    Virtual ist beim Konstruktor dazu da um sicherzustellen, dass der Konstrukor auch korrekt aufgerufen wird, wenn von der Klasse abgeleitet wird.
    Nur verwenden wenn nötig.
    Generell sollte man einen Destruktor auch nur anlegen wenn er unbedingt benötigt wird. In dem Beispiel würde ich ihn weglassen, da er dann vom Compiler automatisch angelegt wird.



  • Ich möchte hier zum Testen Videonauth Code nehmen, aber ohne de dtor Aufruf 😃

    Man muss sich immer behelfen, wenn die Datei geöffnet werden konnte, aber nicht erscheint, dann muss Magie im Spiel gewesen sein. Wenn allerdings die Datei nicht einmal geöffnet wird, dass stimmt was mit den Rechten nicht.

    Und ich schließ mich an, dass auf Win 6/7 unter C: keine Schreibrechte sind. Beim manuellen reinkopieren von Daten muss man oft auf "als Administrator ausführen" gehen. Führ mal dein Prog in Debug/irgendwas.exe als Admin aus, dann geht's bestimmt.

    #include <iostream>
    #include <fstream>
    
    int main(int argc, char* argv[])
    {
        std::fstream filestream;
    
        filestream.open("C:\\Testordner\\Hallotest.txt", std::fstream::out | std::fstream::trunc);
        if(filestream.is_open())
        {
    cout << "Datei wurde geöffnet"; // Wenn das hier kommt, klappte es!
            filestream << "hallo das ist ein test" << std::endl;
            filestream.close();
        }
    cin.get(); // Warte auf Eingabe, damit Konsole nicht gleich verschwindet
        return 0;
    }
    


  • cout << "Datei wurde geöffnet"; // Wenn das hier kommt, klappte es!

    und wenn nicht?
    😉



  • int main()
    {
    	if (auto file = std::ofstream("C:\\test.txt"))
    	{
    		std::cout << "Yaay!\n";
    		file << "Hallo, Welt!\n";
    	}
    	else
    	{
    		std::cout << "Schade ;(\n"; // ("file" existiert auch hier oO :))
    	}
    }
    

    *g* 🤡



  • ich meine eigentlich, was ich dann machen soll?
    ist nämlich der Fall... 😞



  • cooky451 schrieb:

    Also merken: nie, nie, nie, unter keinen Umständen den Destruktor manuell aufrufen. Da hast du dir nicht mehr das Bein abgeschossen, da ist auch gleich der Kopf weg.

    Bei placement new darf man den Destruktor selber aufrufen.



  • JanK411 schrieb:

    ich meine eigentlich, was ich dann machen soll?
    ist nämlich der Fall... 😞

    Testen ob der Ordner existiert und du schreibrechte hast.



  • Aber mit einer Ausnahme hätte es gleich so viel weniger gut geklungen. -.-



  • Wie schon gesagt...
    Fehlermeldun ("Schade ;(") ist gekommen und Ordner wurde nicht erstellt.



  • Da hängst du immer noch dran? Der erste* Post hat dir doch direkt gesagt, dass du auf C:\ keine Schreibrechte hast.

    * Edit: zweite



  • cooky451 schrieb:

    Da hängst du immer noch dran? Der erste* Post hat dir doch direkt gesagt, dass du auf C:\ keine Schreibrechte hast.

    * Edit: zweite

    Naja, in den eigenen Dokumente-Ordner sollte man als einfacher User noch schreiben dürfen - ansonsten würde ja praktisch jede Software nur als Administrator richtig nutzbar sein.

    Was du meinst gilt u.A. für C:\Program Files und C:\Program Files (x86).

    Was jetzt der Fehler im Eingangspost war, weiß ich allerdings auch nicht, allerdigs können Schreibfehler so ausgeschlossen werden:

    #include <windows.h>
    #include <shlobj.h>
    
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    	char c[MAX_PATH];
    	SHGetSpecialFolderPath(0, c, CSIDL_MYDOCUMENTS, false);
    	std::string file = c;
    	file+="\\file.txt";
    	cout << file << "\n";
    
    	std::ofstream stream(file.c_str(), ios::out);
    	if(stream.is_open())
    	{
    		cout << "okay\n";
    		stream << "Sinnvoller Inhalt";
    	}
    	else
    	{
    		cout << "gescheitert...\n";
    	}
    }
    

Anmelden zum Antworten