Lesen von Binär Dateien
-
Ja, Du fragst ab was in die Datei geschrieben werden soll.
Nein, Du schreibst es nicht in den Stream "getAddress".
-
oha... stimmt... ich trottel ^^
und was mach ich falsch beim lesen???
void Read() { cls(); string name; char buf[255]; cout << "Bitte geben sie den Pfad zu der Datei an die sie lesen möchten: "; cin >> name; cls(); setColor(3); ifstream fileOut(name.c_str(),ios::in|ios::binary); if( !fileOut) { openError(); } else { while(!fileOut.eof()) { fileOut.read(buf,255); cout << buf; } } fileOut.close(); }Jetzt hab ich auch noch ein Problem Beim schreiben... Ich krieg eine Fehlermledung nachdem ich den Text der in die Datei geschrieben werden soll eigegeben habe die meistens immer ungefähr so lautet:
Die Anweisung in "0x77c17000 verweist auf Speicher in "0x003d4000". Der Vorgan "read" konnte nicht auf dem Speicher durchgeführt werden.
Klicken Sie auf "OK", um das Programm zu beenden.
Klicken Sie auf "Abbrechen", um das Programm zu debuggen.
hää???
-
@p3ac3:
ÄnderefileOut.read(buf,255); cout << buf;nach
fileOut.read(buf, 254); buf[fileOut.gcount()] = '\0'; cout << buf; ...Merke: operator<<(ostream& os, char*) ließt aus char bis zum Auftreten des '\0'-Zeichens. Wenn du dieses nicht selbst setzt, wird von &buf[0] aus solange aus dem Speicher gelesen, bis entweder das Nullterminierungszeichen gefunden wird, oder aber, weil dir der Speicher aus dem du ließt nicht gehört, es crasht. => Undefiniertes Verhalten = (manchmal geht alles Gut und manchmal - meistens dann, wenn man es am wenigsten gebrauchen kann, chrasht es).
Gruß Caipi
-
danke

jetzt bleibt nur noch das problem beim schreiben. Hab den code nochmal bearbeitet:void Write() { cls(); string name; string name1; setCursor(10,1); cout << "Bitte geben Sie den Pfad an, wo die Datei gespeichert\nwerden soll (z.B. c:\\Hallo.bin): "; cin >> name; ofstream FileIn(name.c_str(),ios::out|ios::binary); if( !FileIn) { openError(); } cls(); cout << "Bitte geben sie nun den Text ein der der Datei hinzugefuegt\nwerden soll: "; cin >> name1; if( !FileIn.write( (char*)name1.c_str(), sizeof(name1)) ) { writeError(); } cls(); FileIn.close(); cout << "Vielen Dank!\n Die Datei ist nun unter '" << name << "' gespeichert!\n Auf Wiedersehen!"; }was mach ich nur falsch...

EDIT: Ein teil des Problems hat sich gelöst. Ich hatte einen schreibfehler. Aber das problem ist das er beim schreiben in die Datei nur bis zur ersten leerstelle schreibt... und dann aufhört. Wie krieg ich das weg

-
p3ac3 schrieb:
if( !FileIn.write( (char*)name1.c_str(), sizeof(name1)) )Hier ist das Problem: sizeof(name1) gibt nicht die Länge des Strings zurück, sondern die Größe der Datenstruktur die diesen String speichert. Wenn sich das zufällig mit dem ersten Leerzeichen in deinem Text überschneidet
Zufall.Die Länge des enthaltenen Strings liefert Dir name1.length()
-
if( !FileIn.write( (char*)name1.c_str(), name1.length()))habs jetzt so ist aber immer noch das gleiche prob...

-
p3ac3 schrieb:
Aber das problem ist das er beim schreiben in die Datei nur bis zur ersten leerstelle schreibt... und dann aufhört. Wie krieg ich das weg

Der istream& operator>>(istream&, string&) ließt nur bis zum nächsten Blank, also (Leerzeichen, Tabstop, New-line, ...). => Verwende die Funktion getline().
edit: Was mir jetzt erst auffällt:
if( !FileIn.write( (char*)name1.c_str(), name1.length()))ist sehr unsauber. (Merke: std::string::c_str() gibt einen const char* zurück. Wenn du diesen in char* castest und dann auf diesen Speicherbereich etwas schreibst erzeugst du undefiniertes Verhalten!).
Gruß Caipi
-
Er schreibt ja hier auch nichts rein. Den Cast kann man sich hier übrigens sparen.
-
Braunstein schrieb:
Er schreibt ja hier auch nichts rein. Den Cast kann man sich hier übrigens sparen.
Jup. Meine Aussage gilt natürlich nur für fstream::read(). (Weiß wirklich nicht, wie es mir gelingt, immer wieder solche "Schussel"-Fehler in die Posts einzubauen
).Gruß Caipi
-
Caipi schrieb:
Braunstein schrieb:
Er schreibt ja hier auch nichts rein. Den Cast kann man sich hier übrigens sparen.
Jup. Meine Aussage gilt natürlich nur für fstream::read(). (Weiß wirklich nicht, wie es mir gelingt, immer wieder solche "Schussel"-Fehler in die Posts einzubauen
).Gruß Caipi
ja,... aber das problem is ja auch beim schreiben. Wenn ich mir diedatei dann anschaue nachdem ich was reingeschrieben habe ohne dieses Programm steht auch nur immer das erste word... (Komisch überhaupt das ich die datei lesen kann, wo sie doch eigentlich binär sein sollte...)

-
1. Wie genau liest du die Datei ein und zeigst sie an? Womöglich ist dort ein NULL-Byte dazwischen, das die Kontollausgabe beendet.
2. Klar kannst du auch die binären Daten lesen, wenn du Text dort reingeschrieben hast. In einer Binärdatei stehen genauso char's wie in einer Textdatei.
(der einzige Unterschied zwischen den Dateimodi ist die Art, wie Newlines behandelt werden - Binärdateien überlesen sie ohne Sonderbehandlung, Textdateien passen sie ans Betriebssystem an (Windows verwendet \r\n, C++ übersetzt das in ein einfaches \n)).
PS@Mods: Warum steht das eigentlich noch nicht in den FAQs? So oft wie diese Frage in letzter Zeit kam.
-
Hallo,
Hinweis für Strings:
Wenn man Strings binär rausschreibt sollte man vorher dort die Länge mit ablegen, sonst weiß man beim späteren Einlesen dann nicht wieviele Bytes gelesen werden sollen.
etwa so// rausschreiben int size = name1.length(); FileIn.write( (char*)size, sizeof(size)); FileIn.write( (char*)name1.c_str(), name1.length())); //einlesen int size; FileIn.read( (char*)size, sizeof(size)); char* buffer = new char[size+1]; FileIn.read( buffer, size); buffer[size] = '\0'; name1 = buffer; delete[] buffer;
-
hallo,
meine Funktionen read() und write() sehen jetzt so aus:void Write() { cls(); string name; string name1; setCursor(10,1); cout << "Bitte geben Sie den Pfad an, wo die Datei gespeichert\nwerden soll (z.B. c:\\Hallo.bin): "; cin >> name; ofstream FileIn(name.c_str(),ios::out|ios::binary); if( !FileIn) { openError(); } cls(); cout << "Bitte geben sie nun den Text ein der der Datei hinzugefuegt\nwerden soll: "; cin >> name1; int size = name1.length(); FileIn.write( (char*)size, sizeof(size)); if( !FileIn.write( name1.c_str(), name1.length())) { writeError(); } cls(); FileIn.close(); cout << "Vielen Dank!\n Die Datei ist nun unter '" << name << "' gespeichert!\n Auf Wiedersehen!"; } void Read() { cls(); string name; setCursor(10,1); cout << "Bitte geben sie den Pfad zu der Datei an die sie lesen moechten: "; cin >> name; cls(); ifstream FileOut(name.c_str(),ios::in|ios::binary); if( !FileOut) { openError(); } else { int size; FileOut.read( (char*)size, sizeof(size)); char* buffer = new char[size+1]; FileOut.read( buffer, size); buffer[size] = '\0'; name = buffer; delete[] buffer; }Aber beim schreiben wird das Programm einfach nachdem ich angegeben habe was in die Datei geschrieben werden soll angegeben habe beendet, wieder mit dieser "Fehler in Der Anwendung" fehlermeldung -> Die Anweisung "0x00435dd9" ... blabla.
??
-
Geh doch mal mit dem Debugger durch und schau wo abgebrochen wird. Desweiteren wirst du beim einlesen mit cin Schwierigkeiten bei Trennzeichen (Leerzeichen oder so) bekommen, da dann hier abgebrochen wird. Nimm lieber getline.
-
getline(cin, name1);richtig?
ok habs durch den debugger laufen lassen aber er zeigt keine fehlermeldungen an...
-
Das mit dem getline ist richtig.
Wenn dein Programm abbricht, muß es doch auch im Debugger abbrechen. Es ist halt wichtig herauszubekommen wo der Fehler auftritt. Ich sehe in deinem Code erstmal keine Fehler.
-
FileOut.write((char*)size,sizeof(size));Da ist ein kleiner, aber dezenter Fehler drin - du interpretierst den Wert von "size" als Adresse der Daten, die du schreiben willst - da ist ein SegFault sehr wahrscheinlich. (und selbst wenn du diese Adresse lesen kannst, steht bestimmt nicht das richtige drin ;))
Richtig müsste es heißen:
FileOut.write(&size,sizeof(size));(PS: Bei der Read()-Funktion hast du den selben Fehler)
-
Ok, war auch mein Fehler. Korrekt müsste es wohl so heißen
FileOut.write((char*)&size,sizeof(size));Der cast ist schon notwendig.
oder noch besserFileOut.write(reinterpret_cast<const char*>(&size),sizeof(size));[edit]const noch eingefügt[/edit]
-
OK! Danke!
Jetzt bricht er nicht mehr ab, aber jetzt habe ich wieder ein neues problem^^(sieht so aus als könnte das nie enden...
) Das Programm überspringt einfach den Teil wo etwas in die Datei geschrieben werden soll. 
EDIT: Kann man eigentlich den text formatieren so das er z.B. rechtsbündig geschrieben wird oder das mal nach einer bestimmten Anzahl von Zeichen ein newline gemacht wird??
-
Weiß keiner was?(sry für doppelpost)