fstream::open(filename, ios::in) löscht Inhalt der Datei



  • Hallo,

    mir ist die Frage schon fast peinlich, aber ich weiß nicht weiter.

    Ich möchte eine Datei öffnen und auslesen. Das mache ich wie folgt:

    #include <stdio.h>
    #include <stdlib.h>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include "Header\UserFunctions.h"
    
    #define MeshFileName "/HybridMesh/HybridPipe.dat"
    
    using namespace std;
    
    	int main(){
    		//Lokal variables
    		string line;
    		unsigned long fi = 0;
    
    		//Checking if file exists
    		if (UserFunctions::FileExist(MeshFileName) == 1){
    			return 1;
    		}
    
    		//Open file for reading and associating
    		fstream MeshFile;
    		MeshFile.open(MeshFileName, ios::in);
    
    		//Looping file
    		while (!MeshFile.eof()){
    			getline(MeshFile, line);
    			fi++;
    		}
    
    		//Closing file
    		MeshFile.close();
    
    		//Output...
    		cout << fi << " lines read. Please press any key to exit program..." << endl;
    		getchar();
    
    		return 0;
    	}
    

    Was ich nicht verstehe: In der Console wird "1 lines read. Please press any key to exit" ausgegeben und die Datei (welcher vorher 2.6 MB groß war) ist auf einmal leer und hat nurnoch 0 KB. Kann mir bitte jemand erklären, wieso das passiert? Ich dachte ios::in ist zum lesen.



  • Ich kann den Fehler nicht nachvollziehen. Wenn dein FileExist nichts kaputt macht, sollte der Inhalt noch da sein.



  • CJens schrieb:

    In der Console wird "1 lines read. Please press any key to exit" ausgegeben und die Datei (welcher vorher 2.6 MB groß war) ist auf einmal leer und hat nurnoch 0 KB.

    2,6 MByte in einer Zeile?

    Ziemlich sicher macht UserFunctions::FileExist die Datei platt.

    Die Verwendung von eof als Schleifenbedingung ist übrigens Käse und offenbar ein unausrottbarer Fehler.



  • ...es ist tatsächlich die FileExist Methode.

    Diese hat folgenden Inhalt:

    #include <stdio.h>
    
    class UserFunctions{
    public:
    	static int FileExist(char* filename){
    		FILE *FilePnt = fopen(filename, "r");
    		if (FilePnt == NULL){
    			return 1;
    		}
    		else {
    			return 0;
    		}
    	}
    
    };
    

    Ist doch eigentlich auch nur Öffnen um zu lesen...


  • Mod

    Das kommt davon, wenn man C-Methoden benutzt, ohne C zu können. 🙄

    Deine Datei ist noch offen. Dein fstream kann sie kein zweites Mal öffnen. Hättest du einen fstream benutzt, wäre das Problem nicht aufgetreten. Hättest du die ganze Funktion nicht (die total unnötig ist), hättest du das Problem auch nicht. Wo ist der Unterschied zwischen deinem

    if (fileExists(dateiname))
    {
      fstream f(dateiname);
      // ...
    }
    

    und

    fstream f(dateiname);
    if (f)
      // ...
    

    ? Das erste ist bloß unnötig umständlich.



  • ...das Ganze sieht jetzt wie folgt aus:

    //Try to open file...
    		fstream MeshFile;
    		MeshFile.open(MeshFileName, ios::in);
    
    		//Checking if file is opened...
    		if (!MeshFile.is_open()){return 1;}
    
    		//Looping file...
    		while (getline(MeshFile, line)){
    			fi++;
    		}
    

    ...und funktioniert wunderbar.



  • 1.- Frag nicht einzelnen bestimmten Fehlern, sondern frag den Stream ob er OK ist.
    2.- Öffne die Datei beim Streamerstellen
    3.- Nutze für Einlesen ifstream und nicht fstream mit in.
    4.- Nutze Konstanten statt Defines
    5.- Nutze mehr Whitespaces und Leerzeilen, das machts übersichtlicher.

    const std::string MeshFileName = "balbalba.dat"; // Nr. 4
    
    // ...
    
    std::ifstream MeshFile(MeshFileName); // Nr 2 und 3
    
    if ( !MeshFile ) { // Nr 1
    	return 1;
    }
    
    while ( getline(MeshFile, line) ) {
    	fi++;
    }
    


  • Skym0sh0 schrieb:

    5.- Nutze mehr Whitespaces und Leerzeilen, das machts übersichtlicher.

    Nö, man kann sie nicht einheitlich sinnvoll setzen, also besser alle weg und nicht so winzige Schriftart wählen.



  • volkard schrieb:

    Skym0sh0 schrieb:

    5.- Nutze mehr Whitespaces und Leerzeilen, das machts übersichtlicher.

    Nö, man kann sie nicht einheitlich sinnvoll setzen, also besser alle weg und nicht so winzige Schriftart wählen.

    Got trolled by Trollmoderator 😃

    Es gibt in den gängigen Tools wie Eclipse, Visual Studio (wahrscheinlich auch CodeBlocks etc.) normalerweise Tastenkombinationen, die den Code autoformatieren. Das würde ich mir halbwegs schön einstellen und benutzen.

    Jeder mag da ja seine eigenen Styles, aber die Hauptsache ist, dass man es halbwegs lesen kann und man nicht beim ersten Blick Augenkrebs kriegt.



  • Skym0sh0 schrieb:

    Got trolled by Trollmoderator 😃

    Nö, ist mein Ernst. Die Suche nach hübschem Spacing kostet mehr, als sie bringt.



  • Zählen da für dich auch Leerzeilen zu?


  • Mod

    volkard schrieb:

    Skym0sh0 schrieb:

    Got trolled by Trollmoderator 😃

    Nö, ist mein Ernst. Die Suche nach hübschem Spacing kostet mehr, als sie bringt.

    Man muss ja nicht suchen. Einfach ein schönes irgendwo abgucken oder eben ein Autospacing der IDE benutzen.



  • Der Umkehrschluss wäre in meinen Augen alles kreuz und quer zu machen, so wie es einem grad passt. Zur Not auch ohne Whitespacing.

    Und spätestens das ist der Punkt wo ich z.B. einem Forum sagen würde: "Das schaue ich mir nicht an"



  • SeppJ schrieb:

    volkard schrieb:

    Skym0sh0 schrieb:

    Got trolled by Trollmoderator 😃

    Nö, ist mein Ernst. Die Suche nach hübschem Spacing kostet mehr, als sie bringt.

    Man muss ja nicht suchen. Einfach ein schönes irgendwo abgucken oder eben ein Autospacing der IDE benutzen.

    4*4 + 3*3
    oder
    4 * 4 + 3 * 3
    ?
    Und das ist ein Faß ohne Boden. Und vällig unnötig, einfach
    4*4+3*3
    !


  • Mod

    Alle 3 sind ok. Tada! Schon hat man eine schöne Einrückung. Aber eben nicht 4 * 4+3 * 3 oder ähnlich verwirrendes.



  • Die sind alle OK. Mir gehts auch weniger um eine dieser 3 Schreibweisen, oder ob und wie die konsistent zueinander sind. Mir geht es ganz pragmatisch um Lesbarkeit.
    Sowas ist zwar wegen seiner Einfachheit noch sehr gut zu lesen, aber bei etwas mehr Komplexität geht da einem ganz schnell die Luft ab.

    #include <iostream>
    int main(int argc, char * argv[]) {
    	int a,b,c,d;
    	std::cout<<"Gib a ein: ";std::cin>>a;
    	std::cout<<"Gib b ein: ";std::cin>>b;
    	std::cout<<"Gib c ein: ";std::cin>>c;
    	std::cout<<"Gib d ein: ";std::cin>>d;
    
    	int e=a+b;int f=c+d;int g=e*f;
    
    	std::cout<<std::endl<<"Ergebnis:"<< g*g << std::endl;
    	return SUCCESS;
    }
    

    Sieht gepresst aus, man könnte bei ungenauem Hingucken etwas Übersehen, etc...

    Das hier ist auf jedenfall gut lesbar, an jeder Stelle und für jeden Programmierer (Details, wie das std:: oder mal en Leerzeichen mehr oder weniger sind dabei offensichtlich egal):

    #include <iostream>
    
    int main(int argc, char * argv[])
    {
    	int a;
    	int b;
    	int c;
    	int d;
    
    	std::cout << "Gib a ein: ";
    	std::cin >> a;
    	std::cout << "Gib b ein: ";
    	std::cin >> b;
    	std::cout << "Gib c ein: ";
    	std::cin >> c;
    	std::cout << "Gib d ein: ";
    	std::cin >> d;
    
    	int e = a + b;
    	int f = c + d;
    	int g = e * f;
    
    	std::cout << std::endl << "Ergebnis: " << g*g << std::endl;
    	return 0;
    }
    


  • Skym0sh0 schrieb:

    Die sind alle OK. Mir gehts auch weniger um eine dieser 3 Schreibweisen, oder ob und wie die konsistent zueinander sind. Mir geht es ganz pragmatisch um Lesbarkeit.
    Sowas ist zwar wegen seiner Einfachheit noch sehr gut zu lesen, aber bei etwas mehr Komplexität geht da einem ganz schnell die Luft ab.

    #include <iostream>
    int main(int argc, char * argv[]) {
    	int a,b,c,d;
    	std::cout<<"Gib a ein: ";std::cin>>a;
    	std::cout<<"Gib b ein: ";std::cin>>b;
    	std::cout<<"Gib c ein: ";std::cin>>c;
    	std::cout<<"Gib d ein: ";std::cin>>d;
    	
    	int e=a+b;int f=c+d;int g=e*f;
    	
    	std::cout<<std::endl<<"Ergebnis:"<< g*g << std::endl;
    	return SUCCESS;
    }
    

    Sieht gepresst aus, man könnte bei ungenauem Hingucken etwas Übersehen, etc...

    Jo, gepresst. Auch für mich sehr häßlich.

    Skym0sh0 schrieb:

    Das hier ist auf jedenfall gut lesbar, an jeder Stelle und für jeden Programmierer (Details, wie das std:: oder mal en Leerzeichen mehr oder weniger sind dabei offensichtlich egal):

    #include <iostream>
    
    int main(int argc, char * argv[])
    {
    	int a;
    	int b;
    	int c;
    	int d;
    	
    	std::cout << "Gib a ein: ";
    	std::cin >> a;
    	std::cout << "Gib b ein: ";
    	std::cin >> b;
    	std::cout << "Gib c ein: ";
    	std::cin >> c;
    	std::cout << "Gib d ein: ";
    	std::cin >> d;
    	
    	int e = a + b;
    	int f = c + d;
    	int g = e * f;
    	
    	std::cout << std::endl << "Ergebnis: " << g*g << std::endl;
    	return 0;
    }
    

    Jo, VIEL besser.

    Aber

    #include <iostream>
    
    int main(int argc, char * argv[])
    {
    	int a;
    	int b;
    	int c;
    	int d;
    
    	std::cout<<"Gib a ein: ";
    	std::cin>>a;
    	std::cout<<"Gib b ein: ";
    	std::cin>>b;
    	std::cout<<"Gib c ein: ";
    	std::cin>>c;
    	std::cout<<"Gib d ein: ";
    	std::cin>>d;
    
    	int e=a+b;
    	int f=c+d;
    	int g=e*f;
    
    	std::cout<<std::endl<<"Ergebnis: "<<g*g<<std::endl;
    	return 0;
    }
    

    ist mir leiber. Türlich (normalerweise) eine eigene Zeile pro Zweck. Und zwischen größeren Sinn-Einheiten auch mal eine Leerzeile.

    Wobei gerade da zu überlegen wäre

    #include <iostream>
    
    int main(int argc, char * argv[])
    {
    	int a; std::cout<<"Gib a ein: "; std::cin>>a;
    	int b; std::cout<<"Gib b ein: "; std::cin>>b;
    	int c; std::cout<<"Gib c ein: "; std::cin>>c;
    	int d; std::cout<<"Gib d ein: "; std::cin>>d;
    
    	int e=a+b;
    	int f=c+d;
    	int g=e*f;
    
    	std::cout<<std::endl<<"Ergebnis: "<<g*g<<std::endl;
    	return 0;
    }
    

    Also gleichartigen Code ausnahmsweise mal anders zu formatieren, damit die Gleicharigkeit offensichtlich wird, der Code wird damit "langweiliger" und langweiliger Code ist supi, da verstecken sich weniger Fehler. (Ja, ich weiß, man denkt an böse Codeduplikatiohn und

    int a=gibEin<int>('a');
    

    ).

    Kann mich nicht daran erinnern, daß mal jemend meinen geposteten Code angemeckert hätte, es wären zu wenige Leerzeichen drin, vielleicht waren mal Marc++us zu wenige Leerzeilen drin.

    Wenn Nube-Code zu unleserlich ist, liegt's vielleicht nicht an den Leerzeichen, sondern daß der Code selber umständlich ist. So Laufbedingungen mit 5 && oder || drin, wo mir schon eins davon Bauchweh bereitet, und zwei davon habe ich eigentlich nie. Oder ellenlange Rechnungen ohne aussagekräftige Zwischenergebnisse, ich würde kaum V=PI*(d/2)*(d/2)*h; schreiben, wenn V=G*h; reicht.

    edit: Warum ist das return nicht abgesetzt, hat ja nix mit dem Rest zu tun?


Anmelden zum Antworten