Problem mit Standard-Streams bwz. ifstream per Hand initialisieren



  • Hi Leute!
    Falls "iostream" Profis da sind, bitte hersehen!

    Ich will im Prinzip ifstream von Hand initialisieren.

    Problem ganz kurz: bei der Ausgabe des 2. Buffer fehlen am Anfang Zeichen.

    Hier mal der Code:

    ifstream A("u.txt",ios::in);
    
    	if(!A.good())
    	{
    		cout<<"File not Found!"<<endl;
    		return(1);
    	}
    
    	A.seekg (0, ios::end);
        int Size= A.tellg();
        A.seekg (0, ios::beg);
    
    	char *Buffer= new char[Size];
    	A.read(Buffer, Size);
    
    	cout<<Buffer<<endl;
    
    	cout<<endl<<endl<<endl;
    
    	ifstream B;
    	B.rdbuf()->pubsetbuf(Buffer, Size);
    
    	delete[] Buffer;
    	Buffer= new char[Size];
    
    	B.read(Buffer, Size);
    
    	cout<<Buffer<<endl;
    

    u.txt ist eine ganz normale txt.

    Bitte um Hilfe!
    Danke!



  • Ich weiss nicht, ob das den Fehler verursacht, aber mit new[] angelegter Speicher muss entsprechend mit delete[] freigegeben werden.

    delete Buffer;   // ist also falsch.
    delete[] Buffer; // wäre richtig.
    


  • Nein daran hat's nicht gelegen!


  • Administrator

    In dem Code hat es meiner Meinung nach zwei Fehler, ich kommentiere sie mal rein in den Code:

    ifstream A("u.txt",ios::in);
    
    	if(!A.good())
    	{
    		cout<<"File not Found!"<<endl;
    		return(1);
    	}
    
    	A.seekg (0, ios::end);
        int Size= A.tellg();
        A.seekg (0, ios::beg);
    
    	char *Buffer= new char[Size];
    	A.read(Buffer, Size);
    
    	cout<<Buffer<<endl; // Fehler! Undefiniertes Verhalten! Buffer hat keine Null-Terminierung.
    	// Besser wäre wohl sowas:
    	cout << string(Buffer, Size) << endl;
    
    	cout<<endl<<endl<<endl;
    
    	ifstream B;
    	B.rdbuf()->pubsetbuf(Buffer, Size);
    
    	delete[] Buffer; // Das könnte wohl auch zu einem Fehler führen.
            // B.rdbuf()->pubsetbuf(Buffer, Size) kopiert glaub ich nicht das Array,
    	// sondern ersetzt es intern. Du löchst aber nun den Speicherbereich und 
    	// verwendest ihn dann später. Das ist dann wohl garantiert undefiniertes Verhalten.
    	Buffer= new char[Size];
    
    	B.read(Buffer, Size);
    
    	cout<<Buffer<<endl;
    

    Grüssli



  • std::vector statt char*



  • nochwas schrieb:

    std::vector statt char*

    Nur wird als Puffer ein char* benötigt.



  • Blaze schrieb:

    ifstream A("u.txt",ios::in);
    
    	if(!A.good())
    	{
    		cout<<"File not Found!"<<endl;
    		return(1);
    	}
    
    	A.seekg (0, ios::end);
        int Size= A.tellg();
        A.seekg (0, ios::beg);
    
    	char *Buffer= new char[Size];
    	A.read(Buffer, Size);
    
    	cout<<Buffer<<endl;
    
    	cout<<endl<<endl<<endl;
    
    	ifstream B;
    	B.rdbuf()->pubsetbuf(Buffer, Size);
    
    	delete[] Buffer;
    	Buffer= new char[Size];
    
    	B.read(Buffer, Size);
    
    	cout<<Buffer<<endl;
    

    Wozu machst du sowas ? Vllt. wäre istringstream was für dich:

    ifstream input("u.txt");
    istream_iterator<char> start(input), end;
    
    string buffer(start, end);
    
    istringstream istr(buffer);
    istr >> buffer;
    

    Einen Sinn endeckte ich aber darin immernoch nicht 🙂



  • Nexus schrieb:

    nochwas schrieb:

    std::vector statt char*

    Nur wird als Puffer ein char* benötigt.

    &vec[0] ?



  • Danke für eure Hilfe!
    Ich hab das Problem inzwischen anders gelöst, über virtuelle Datein



  • Blaze schrieb:

    Danke für eure Hilfe!
    Ich hab das Problem inzwischen anders gelöst, über virtuelle Datein

    Was aber rein gar nichts mit dem Fehler zu tun hat. Aber anscheinend hast du alles neu geschrieben und wahrscheinlich auch sinnvolleren Code produziert. 😉



  • drakon schrieb:

    wahrscheinlich auch sinnvolleren Code produziert. 😉

    Jein!
    Erst hatte ich ifstream zum Einlesen gekapselt, das habe ich aber durch eine eigene Klasse für virtuelle Datein ersetzt.
    Damit muss ich nicht zum Beispiel Speicherblöcke aus geladenen Windows-Resourcen in den Puffer von istream legen, etc. Sondern habe jetzt alles schön in einer Klasse.


Anmelden zum Antworten