Fehlermeldung bei Verwendung von ifstream
-
Hallo zusammen,
warum bekomme ich mit diesem Beispiel (C++Builder 2010) eine Fehlermeldung
Wo hab ich denn da einen Überlauf ? Die Fehlermeldung kommt schon beim Aufrufen der Zeile 26.//--------------------------------------------------------------------------- #include <vcl.h> #include <iostream> #include <fstream> #include <string> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" using namespace std; TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { string strZeile; ifstream SrcFile( SourceEdt->Text.c_str(), ios::in | ios::binary ); //if ( SrcFile.good() ) if ( SrcFile != 0 ) { ListBox1->Items->Add ( "Öffne Datei " + SourceEdt->Text ); while ( !SrcFile.eof() ) { getline( SrcFile, strZeile ); ListBox1->Items->Add( strZeile.c_str() ); } } else { ListBox1->Items->Add ( "Kann Datei " + SourceEdt->Text + " nicht öffnen !" ); return; } SrcFile.close(); } //---------------------------------------------------------------------------
Fehlermeldung:
05.01.2011 16:07:36 CodeGuard(tm)-Prozess wurde gestartet: Test.exe(508) Zugriff Überlauf im Prozess: Test.exe(508) - c:\program files\embarcadero\rad studio\7.0\include\../include/dinkumware/fstream#157 Versuch auf 520 Byte(s) bei 0x01CAFDAC zuzugreifen, das ist bei Offset 12 in Heap block 0x01CAFDA0, der nur 38 Byte lang ist. 0x004CFB2C Aufruf von wcstombs(0x0012F190 ["J�\f��"], 0x01CAFDAC, 0x104 [260]) 0x004B76FE 0x00403184 - c:\program files\embarcadero\rad studio\7.0\include\../include/dinkumware/fstream#157 0x00402709 - c:\program files\embarcadero\rad studio\7.0\include\../include/dinkumware/fstream#647 0x00401F36 - Unit1.cpp#27 0x004A7ED9 - Controls.pas#7179 0x004AC235 - Controls.pas#9821 Speicherblock (0x01CAFDA0) [Größe: 38 Byte] war Bereitgestellt mit SysGetMem 0x0044B29A - System.pas#2983 0x004A7ED9 - Controls.pas#7179 0x004AC235 - Controls.pas#9821 0x00463ABD - StdCtrls.pas#4365 0x004AC388 - Controls.pas#9888 0x004AC235 - Controls.pas#9821
-
Hab das Problem gefunden, aber noch nicht verstanden. Wenn ich folgende Zeile ändere funktioniert es:
// geht nicht ifstream SrcFile( SourceEdt->Text.c_str(), ios::in | ios::binary ); // so funktioniert es ifstream SrcFile( "C:\\Temp\\Testfile.txt", ios::in | ios::binary );
Wieso kann das nicht aus dem Edit-Feld ausgelesen werden ? Liegt das am "c_str()" ?
-
auf meinem CBuilder 6 geht das ohne Probleme.
Versuche es doch mal so:ifstream SrcFile; SrcFile.open(SourceEdt->Text.c_str() , ios::in | ios::binary );
Gruß myerscola
-
myerscola schrieb:
auf meinem CBuilder 6 geht das ohne Probleme.
Der hat auch kein Unicode. Beim BCB 6 gilt String = AnsiString, seit 2009 String = UnicodeString.
Versuch mal
AnsiString(SourceEdt->Text).c_str()
-
Hi nn,
das war der Knackpunkt, damit geht's. Aber verstehen tu ich es nicht, selbst diese beiden Versionen funktionieren nicht:
// hier kommt zwar kein Abbruch, aber NULL Pointer zurück ifstream SrcFile( SourceEdt->Text.t_str(), ios::in | ios::binary ); // selbst mit der "Unicode" Version von ifstream geht es auch nur über AnsiString() wifstream SrcFile( SourceEdt->Text.c_str(), ios::in | ios::binary );
Wäre das eine "korrekte" Unicode Variante mit wifstream ? getline() ?
void __fastcall TForm1::Button2Click(TObject *Sender) { wstring strZeile; wifstream SrcFile( AnsiString( SourceEdt->Text ).c_str(), ios::in | ios::binary ); if ( SrcFile.good() ) { ListBox1->Items->Add ( "Öffne Datei " + SourceEdt->Text ); while ( !SrcFile.eof() ) { getline( SrcFile, strZeile ); ListBox1->Items->Add( strZeile.c_str() ); } } else { ListBox1->Items->Add ( "Kann Datei " + SourceEdt->Text + " nicht öffnen !" ); return; } SrcFile.close(); }
-
Verstehen tue ich es auch nicht ganz, ich habe gerade keinen C++ Builder in Reichweite, muss das bei Gelegenheit mal testen.
ifstream und wifstream sollten eigentlich beide char* oder wchar_t* als Dateinamen akzeptieren. Jedenfall tuen sie es bei der Konkurenz:
http://msdn.microsoft.com/de-de/library/zek0beca.aspxt_str() soll man übrigens nicht benutzen:
http://blogs.embarcadero.com/ddean/2010/09/10/34867
-
nn schrieb:
Verstehen tue ich es auch nicht ganz, ich habe gerade keinen C++ Builder in Reichweite, muss das bei Gelegenheit mal testen.
ifstream und wifstream sollten eigentlich beide char* oder wchar_t* als Dateinamen akzeptieren. Jedenfall tuen sie es bei der Konkurenz:
Laut C++ Standard akzeptiert der ifstream-Konstruktor nur const char* für den Filenamen aber kein wchar_t*. Scheint also eine MS-Erweiterung zu sein.
-
Dann hätte ich aber eine Fehlermeldung erwartet, wenn eine Funktion const char* erwartet, aber const wchar_t* bekommt ...
-
So, ich konnte es jetzt mit dem 2010er testen ...
Braunstein schrieb:
Laut C++ Standard akzeptiert der ifstream-Konstruktor nur const char* für den Filenamen aber kein wchar_t*. Scheint also eine MS-Erweiterung zu sein.
Er geht aber nach
explicit basic_ifstream(const wchar_t *_Filename, ios_base::openmode _Mode = ios_base::in, int _Prot = (int)ios_base::_Openprot) : basic_istream<_Elem, _Traits>(&_Filebuffer) { // construct with wide-named file -- EXTENSION if (_Filebuffer.open(_Filename, _Mode | ios_base::in, _Prot) == 0) _Myios::setstate(ios_base::failbit); }
im fstream Header.
Deshalb sagt der Compiler also nix.
Und das
void __fastcall TfrmMain::btnStreamClick(TObject *Sender) { String name = L"Test.txt"; string s; ifstream dat(name.c_str()); while (!dat.eof()) { getline(dat, s); } }
läuft ohne Probleme.
-
Hmm, das ergibt bei mir den gleichen Fehler. Allerdings nur, wenn ich unter C++Compiler->Debuggen->Codeguard aktivieren = true gesetzt habe
Compilieren macht er ohne Fehlermeldung, nur beim Ausführen kommt wieder die Fehlermeldung vom Codeguard. Wenn ich den Codeguard deaktiviere läuft das Programm durch ?!void __fastcall TfrmMain::btnStreamClick(TObject *Sender) { String name = L"Test.txt"; string s; ifstream dat(name.c_str()); while (!dat.eof()) { getline(dat, s); } }
11.01.2011 08:30:44 CodeGuard(tm)-Prozess wurde gestartet: Test.exe(4640) Zugriff Überlauf im Prozess: Test.exe(4640) Versuch auf 520 Byte(s) bei 0x01CEF56C zuzugreifen, das ist bei Offset 12 in Heap block 0x01CEF560, der nur 38 Byte lang ist. 0x004E4040 Aufruf von wcstombs(0x0012EB74 ["��"], 0x01CEF56C, 0x104 [260]) 0x004CEDEA 0x0040ED81 0x004BF5C5 0x004C3921 0x0047B1A9 0x004C3A74 Speicherblock (0x01CEF560) [Größe: 38 Byte] war Bereitgestellt mit SysGetMem 0x0045E60E 0x004EA405 0x0040DB50 0x004BF5C5 0x004C3921 0x0047B1A9
-
Da müsste man mal den Code anschauen, ob da bei der Zeichensatzumwandlung falsch auf Speicher zugegriffen wird, oder der Fehler in Codeguard liegt.
Aber wenn da intern wcstombs aufgerufen wird, kannst du auch gleich die Variante mit dem AnsiString nehmen, die macht die gleiche Umwandlung, nur an anderer Stelle.
-
nn schrieb:
So, ich konnte es jetzt mit dem 2010er testen ...
Braunstein schrieb:
Laut C++ Standard akzeptiert der ifstream-Konstruktor nur const char* für den Filenamen aber kein wchar_t*. Scheint also eine MS-Erweiterung zu sein.
Er geht aber nach
...
läuft ohne Probleme.Das widerspricht doch in keiner Weise meiner Aussage. Die Compilerhersteller haben doch durchaus die Möglichkeit die Standardbibliotheken über den Standard hinaus zu erweitern.
-
Braunstein schrieb:
Das widerspricht doch in keiner Weise meiner Aussage.
Aber der Doku vom Builder 2010.
-
nn schrieb:
Da müsste man mal den Code anschauen, ob da bei der Zeichensatzumwandlung falsch auf Speicher zugegriffen wird, oder der Fehler in Codeguard liegt.
Aber wenn da intern wcstombs aufgerufen wird, kannst du auch gleich die Variante mit dem AnsiString nehmen, die macht die gleiche Umwandlung, nur an anderer Stelle.
Naja an Code ist da nichts weiters drin als dieser Button-Click. Dann liegt es wohl tatsächlich an dem Codeguard und es ist kein Fehler im Programm-Code.
Wenn ich im normalen Debug Modus das Programm erzeuge geht es auch, nur mit Codeguard aktiviert bringt er diesen Fehler. Ich dachte mit Codeguard sollte ein fehlerfreier Programm-Code immer durchlaufen
-
Ich habe das selbe Problem mit Codegard......ist traurig aber wahr.
Kennt vllt jmd eine Prgama-Anweisung um Codegard für einzelne Zeilen auszuschalten?