ERLEDIGT
JA
JA
ANTWORTEN
12
12
ZUGRIFFE
1657
1657
EMPFEHLEN
-
Hi,
ich muss in einer Datei Namen von Personen binär abspeichern.
Dies klappt auch bereits.
Wie kann ich allerdings diese Namen wieder einlesen, sodass ich z.B die Ausgabe so gestalten könnte:
1. Name:
2. Name:
Hier einmal mein Code:
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
// dateihandler.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <conio.h> #include <string> #include <fstream> // wg. Dateioperationen using namespace std; void einlesen() { ifstream start; start.open("namen.dat", ios::in|ios::binary); if (!start) { // Datei kann nicht geoeffnet werden cerr << "namen.dat" << " kann nicht geöffnet werden!\n"; exit(-2); } //eingabe.read((char *)&d, sizeof(d)); //eingabe.close(); } void schreiben(string x) { ofstream ziel; // Zieldatei (Schreiben) ziel.open("namen.dat", ios::out|ios::app|ios::binary); // zum Schreiben öffnen if (!ziel) { // Datei kann nicht geoeffnet werden cerr << "namen.dat" << " kann nicht geöffnet werden!\n"; exit(-2); } ziel.write((char *)&x, sizeof(x)); //ziel.close(); kann weggelassen werden, da in Funktionen automatisch geschlossen wird } int _tmain(int argc, _TCHAR* argv[]) { string test; cout << "Namen eingeben"<<endl; cin >> test; schreiben(test); getch(); return 0; }
-
13.04.09 22:04 #2
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Das ist ein Irrtum. Hast du mal in die Datei geschaut? Oder wie groß die Datei ist?
Du mußt schon direkt die Daten in die Datei schreiben, und nicht einfach die Adresse eines Funktionsparameters. Diese Adresse ist nämlich bereits nach Verlassen der Funktion wieder ungültig, vor allem nach einem Neustart des Programmes.
Es wäre evtl. eine gute Idee, die Strings so zu speichern, das du zuerst die Länge als int in die Datei schreibst und dann die Daten des Strings, so dass du nachher beim Einlesen die Information über die Länge der Daten hast und diese direkt Einlesen kannst:Code cpp:1 2 3
string s; ziel.write(s.data(), s.size());
Fehlerbehandlung bzw. Überprüfung des Einlesens lass ich mal weg. Evlt. solltest du auch einfach mal nach anderen Themen hier suchen.Code cpp:1 2 3 4 5
int size; start.read(reinterpret_cast<char*>(&size), sizeof(size)); char* s = new char[size]; start.read(s, size);
GrußIf at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
Danke für deineAntwort.
Hab es jetzt einmal umgebaut.
Soweit wie ich das nun beurteilen kann, läuft es auch.
Allerdings habe ich mit der Ausgabe noch ein Problem. Diese gibt mir natürlich nur den ersten Datensatz aus. Wie kann ich in einem Rutsch alle Datensätze aufeinmal aus der Datei einlesen und ausgeben?
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
struct start_destination { char start[50]; char destination[50]; }; void write_binary_file(start_destination p_Data) { ofstream binary_file;// Zieldatei (Schreiben) binary_file.open("test.dat", ios::out|ios::app|ios::binary); // zum Schreiben öffnen if (!binary_file) { // Datei kann nicht geoeffnet werden cerr << "test.dat" << " kann nicht geoeffnet werden!\n"; getch(); } binary_file.write(reinterpret_cast<char *>(&p_Data),sizeof(start_destination)); binary_file.close(); } void read_binary_file() { start_destination p_Data; ifstream binary_file; binary_file.open("test.dat", ios::in|ios::binary); if (!binary_file) { // Datei kann nicht geoeffnet werden cerr << "test.dat" << " kann nicht geoeffnet werden!\n"; getch(); } binary_file.read(reinterpret_cast<char *>(&p_Data),sizeof(start_destination)); binary_file.close(); cout<<"Start: "<<p_Data.start<<endl; cout<<"Destination :"<< p_Data.destination<<endl; }
-
14.04.09 13:37 #4
Moin,
beispielsweise so:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
FILE *stream; long numread = 0; int iFileHandle = 0; rsp_datalen = 0; iFileHandle = _access(strFileName, 0); if( iFileHandle != -1) { iFileHandle = _sopen (strFileName, _O_RDONLY, _SH_DENYNO); if (iFileHandle != -1) { numread = _lseek( iFileHandle, 0L, SEEK_END ); _close(fh); // in "numread" steht jetzt die Anzahl der zu lesenden Zeichen } }
Jetzt weißt an der Stelle also, wieviele Zeichen insgesamt zu lesen sind!
Nutze entweder den Tipp von deepthroat, jeweils die Länge der einzelnen Namen mit abzuspeichern, oder speichere ein beliebiges Trennzeichen (etwa ';' oder '#') nach jedem Namen. Im letzteren Fall kannst Du dann sogar bequem über RegEx splitten!
Gruß
KlausEs ist noch kein Meister vom Himmel gefallen - sonst hätte man schon längst seine Leiche gefunden !!
Falls ich helfen konnte, wäre eine Bewertung oder ein Danke nett ;-)
-------------------------------------------------------------------------------------------------
Ich beantworte keine Fragen per PN !!
Stellt Eure Fragen im Forum - dann haben alle etwas davon !!
-
14.04.09 15:05 #5
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Hi.Aber warum auf diese Weise? Da verschwendest du jetzt einen Haufen Speicher und bist natürlich auch nicht flexibel. Warum bleibst du denn nicht bei den std::strings?
Am einfachsten implementierst du je eine Funktion die einen Stream und einen String übergeben bekommt. So kannst du die Datei öffnen und für jeden Datensatz die Funktion aufrufen:
@vfl_freak: Warum sollte man das denn unbedingt auf diese Weise machen und alles komplett in den Speicher lesen? Wozu sollte man die Lowlevel Funktionen statt der iostreams verwenden?Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14
bool read_data(istream& in, was_auch_immer& data) { was_auch_immer temp; if (in.read(reinterpret_cast<char*>(&temp, size?)) { data.swap(temp); return true; } else return false; } ifstream file("abc.dat", ios::binary | ios::in); was_auch_immer entry; while (read_data(file, entry)) { // Ausgabe von entry }
GrußIf at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
14.04.09 15:17 #6Es ist noch kein Meister vom Himmel gefallen - sonst hätte man schon längst seine Leiche gefunden !!
Falls ich helfen konnte, wäre eine Bewertung oder ein Danke nett ;-)
-------------------------------------------------------------------------------------------------
Ich beantworte keine Fragen per PN !!
Stellt Eure Fragen im Forum - dann haben alle etwas davon !!
-
14.04.09 15:38 #7
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
If at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
14.04.09 15:52 #8
Moin,
Weil das hier in dem Projekt, was ich übernommen habe, ein einer der vielen Hilfsfunktionen so steckt! Sicher kann man das auch anders (einfacher) machen, aber bei über 60.000 Zeilen bleibt sowas dann meist einfach drin mit den lapidaren Hinweis: historisch gewachsen!
Plattformunabhängigkeit ist hier bei uns eh' nicht das Thema .....
Und man halt i. d. R. nicht die Zeit, um Dinge die funktionioeren zu anderen Dingen umzubauen, die genauso funktionieren .....
Ok, das mag sein, aber zum einen gibt es dann dafür Hilfen und zum anderen wage ich dann zu bezweifeln, dass ein Anfänger so auf Abhieb weiß, was bspw. ein "reinterpret_cast" ist.
Wir formulieren hier doch meist alle unsere Antworten mehr nach dem eigenen Wissensstand, zumal ja auch meist nicht klar ist, was ein Fragesteller weiß und was nicht ....
Gruß
KlausEs ist noch kein Meister vom Himmel gefallen - sonst hätte man schon längst seine Leiche gefunden !!
Falls ich helfen konnte, wäre eine Bewertung oder ein Danke nett ;-)
-------------------------------------------------------------------------------------------------
Ich beantworte keine Fragen per PN !!
Stellt Eure Fragen im Forum - dann haben alle etwas davon !!
-
14.04.09 16:42 #9
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Die Bedeutung eines Schlüsselwortes kann man relativ schnell nachschauen, aber einen (etwas) komplexeren Codeschnipsel überschaut man nicht so schnell.
Das mag sein, aber da kann man auch nicht davon ausgehen, das ein Fragesteller ein Windows Betriebssystem einsetzt...
Außerdem finde ich es bedenklich Anfängern Code an die Hand zu geben, der (evtl.) selbst nicht richtig verstanden wird, nur in der Form verwendet wird weil historisch so gewachsen / von irgendjemand mal so geschrieben, Sicherheitsprobleme verursacht bzw. einfach falsch ist.
Wenn man hier Antworten postet, sollte man doch darauf achten, das Anfänger dazu neigen den hier präsentierten Code als "das gelbe vom Ei" zu betrachten und das sich auf diese Weise manche Irrtümer und schlechte Angewohnheiten verbreiten.
GrußIf at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
Hatte jetzt wieder zeit mich meinem Problem zu widmen.
Meine Funktion gibt mir nun alle Einträge aus, allerdings wird der letzte Eintrag doppelt ausgegeben.
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
void read_from_binary_file() { start_destination p_Data; ifstream binary_file; binary_file.open("test.dat", ios::in|ios::binary); if (!binary_file) { // Datei kann nicht geoeffnet werden cerr << "test.dat" << " kann nicht geoeffnet werden!\n"; getch(); } while (!binary_file.eof()) { binary_file.read(reinterpret_cast<char *>(&p_Data),sizeof(start_destination)); cout<<"Start: "<<p_Data.start<<endl; cout<<"Destination :"<< p_Data.destination<<endl; } binary_file.close(); }
-
24.04.09 15:48 #11
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Hi.Ach, es ist immer wieder das gleiche.
Und da hab ich es dir schon vorgemacht...
Nicht so:Sondern so:Code cpp:1 2
while (!binary_file.eof()) { binary_file.read(reinterpret_cast<char *>(&p_Data),sizeof(start_destination));
GrußCode cpp:1
while (binary_file.read(reinterpret_cast<char *>(&p_Data),sizeof(start_destination)) {
If at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
Hi,
ich hab den code ein bisschen erweitert, bzw. in eine Klasse eingebaut.
Bevor ich nun einen neuen Thread aufmache poste ich es hier.
Das schreiben an sich klappt. Allerding wird der Name des Ortes nicht gespeichert.
Anscheined klappt bei der Umwandlung von string in char etwas nicht.
Die get-Methode "get_name" liefert einen String mit dem Namen des Ortes zurück.
Hier einmal der Code.
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
void write_to_binary_file() { struct daten { char test[30]; int x_ko; int y_ko; }; daten p_daten; const char *x; struct knoten *p = anfang; ofstream binary_file;// Zieldatei (Schreiben) binary_file.open("binaer.dat", ios::out|ios::binary); // zum Schreiben öffnen if (!binary_file) { // Datei kann nicht geoeffnet werden cerr << "binaer.dat" << " kann nicht geoeffnet werden!\n"; getch(); } while (p != NULL) { x = p->info.get_name().c_str();//string zu char umwandeln strcpy( p_daten.test, x); p_daten.x_ko = p->info.get_x_koordinate(); p_daten.y_ko = p->info.get_y_koordinate(); binary_file.write(reinterpret_cast<char *>(&p_daten),sizeof(daten)); p = p->next; // p auf Folgeelement setzen } binary_file.close(); }
-
08.05.09 11:14 #13
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Hi.Das geht so nicht. Die get_name() Methode liefert ein temporäres Objekt. Die c_str() Methode liefert einen entsprechenden Zeiger auf die Daten dieses temporären Objektes den du dann speicherst.
Das temporäre Objekt wird üblicherweise gleich wieder weggeräumt, so das du einen ungültigen Zeiger hast.
Vermeide die Verwendung von Zeigern.
GrußCode cpp:1
strcpy(p_daten.test, p->info.get_name().c_str());
If at first you don't succeed, try again. Then quit. No use being a damn fool about it.
Ähnliche Themen
-
Binär struct tm schreiben und lesen?!
Von Metzlmane im Forum C/C++Antworten: 7Letzter Beitrag: 13.05.09, 22:06 -
Ints und bools Binär lesen/schreiben
Von liggi im Forum C/C++Antworten: 0Letzter Beitrag: 04.10.08, 13:57 -
Datei lesen/schreiben binär/hex
Von Thomasio im Forum C/C++Antworten: 1Letzter Beitrag: 15.01.08, 19:03 -
binär in datei schreiben
Von zapp91 im Forum C/C++Antworten: 9Letzter Beitrag: 10.10.07, 16:03 -
Zeilenweise aus Ini Datei lesen und in neue Datei schreiben
Von Putzwied im Forum C/C++Antworten: 2Letzter Beitrag: 27.04.07, 08:16





Zitieren

Login






