Array speichern
-
Hallo
Meine Ideen waren:
- Vorher ein Int-Wert abspeichern der angibt wieviele Elemente das Array hat und aus dieser Angabe das neue Array zu erzeugen.Ist okay
- Erst alles in ein übergroßes Array zu laden in dem aufjedenfall alle reinpassen dann die Elemente zählen (oder beim auslesen mitzählen) ein zweites array erzeugen,
die Elemente kopieren, dann das Buffer-Array löschenIst schlecht, weil du dann wieder eine (zwar große) Maximalgröße und dazu noch Kopieroverhead hast
Die eigentliche Lösung ist die Verwendung eines dynamischen Arrays. Das VCL-Mittel dafür ist DynamicArray (siehe Suche hier im BCB-Forum), ich empfehle dir aber das wesentlich elegantere und umfangreichere Mittel aus dem C++ Standard : std::vector (siehe Suche im C++ Forum, sowie den Magazin-Artikel über die STL-Container).
Bei beitem hast du am Anfang ein leeres Array. Mit einer while-Schleife liest du solange ein, bis du am Ende der Datei bist. Bei jedem Durchgang liest du die Werte für ein Element ein und hängst es an das Array.
bis bald
akari
-
Habs jetzt mit der ersten Methode versucht...
leider wird nur der Intergerwert ausgelesen...Ich vermutet stark das es etwas damit zu tun hat das ich String-Wert abspeichern will... kann es sein das sich nur char binär abspeichern lassen===
hier mal der Quelltext von dem Programm das in die Datei schreibt:
//--------------------------------------------------------------------------- #include <vcl.h> #include <fstream> #include <iostream> #pragma hdrstop using namespace std; #pragma argsused int main(int argc, char* argv[]) { String Searchword[]={"hallo","hallo1","hallo2","hallo3"}; fstream File("List.dat", ios::out|ios::binary); if (File.is_open()) { int Size = sizeof(Searchword)/sizeof(Searchword[0]); File.write((const char*)&Size, sizeof(Size)); for(int i=0; i < sizeof(Searchword)/sizeof(Searchword[0]); i++) { String Buffer = Searchword[i]; File.write((const char*)&Buffer, sizeof(Buffer)); } File.close(); // Datei schließen } system("PAUSE"); return 0; }Hier von dem Programm das rauslesen soll...
//--------------------------------------------------------------------------- #include <vcl.h>2 #include <fstream> #include <iostream> #pragma hdrstop using namespace std; #pragma argsused int main(int argc, char* argv[]) { fstream File2("List.dat", ios::in|ios::binary); if (File2.is_open()) { int Size; File2.read((char*)&Size, sizeof(Size)); cout << "Array-Size = "<<Size<<endl; //String *Searchword = new String[Size]; for(int i=0;i < Size; i++) { String Buffer; File2.read((char*)&Buffer, sizeof(Buffer)); cout << Buffer.c_str() << "#" << endl; } } File2.close(); system("PAUSE"); return 0; } //---------------------------------------------------------------------------oder liegt mein Fehler woanders???
wenn es an den strings liegt ist es dann möglich so etwas
char test[40];in ein array zu packen?? ist ja schon ein array an sich...
oder muss ich dann eine zweite dimension dazu nehmen??Schonmal vielen Dank für die Antworten!!
MfG Straightflush
-
Hallo,
Du hast da oben ein Array von AnsiStrings. Wenn du die binär rausschreiben willst, mußt du nicht nur die Größe des Array, sondern auch die Länge jedes Einzelstrings mit ausgeben.
File.write((const char*)&Buffer, sizeof(Buffer));Das hier geht schon gar nicht. Du castest ein AnsiString in ein const char*. Ich weiß jetzt nicht was dabei rauskommt, aber mit Sicherheit nicht das was du erwartest. sizeof(Buffer) gibt dir auch nicht die Länge des Strings, sondern nur die Größe einer AnsiStringinstanz.
Einen AnsiString kann man so rausschreiben.int len = Buffer.Length(); File.write((const char*)&len, sizeof(len)); File.write(Buffer.c_str(), len);und so mußt du es auch einlesen. Erst die Länge, dann die Anzahl der Bytes in einen char* Puffer un zu Schluß das in den AnsiString.
Bsp.int len; File2.read((char*)&len, sizeof(len)); char* buffer = new char[len+1]; File2.read((buffer,len); buffer[len] = '\0'; String str = buffer; delete[] buffer;Du kannst auch alles im Textmodus rausschreiben. Dann wird zwar die Datei etwas größer und von jedem lesbar. Allerdings vereinfacht sich das Lesen und schreiben stark.
-
Habs so versucht...
Bekomme leider immer die Meldung "Speicheradresse muss verwendet werden"...//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include <fstream> using namespace std; #include <iostream> //--------------------------------------------------------------------------- #pragma argsused int main(int argc, char* argv[]) { String Searchword[]={"hallo","hallo1","hallo2","hallo3"}; fstream File("List.dat", ios::out|ios::binary); if (File.is_open()) // Wenn Datei geöffnet ist { int Size = sizeof(Searchword)/sizeof(Searchword[0]); // Anzahl der Suchwörter berechnen File.write((const char*)&Size, sizeof(Size)); // und in Datei abspeichern for(int i=0; i < sizeof(Searchword)/sizeof(Searchword[0]); i++)//Anzahl der Durchläufe entspricht Anzahl der Suchwörter { cout << Searchword[i].c_str() << " hat die laenge: " << Searchword[i].Length() << endl; int len = Searchword[i].Length(); File.write((const char*)&len, sizeof(len)); // Größe des Wortes in Datei speichern File.write(&Searchword[i].c_str(), len); // Wort in char und dann in Datei speichern <-------- HIER IST DIE FEHLERZEILE cout << Searchword[i].c_str() << " wurde mit der Laenge: " << len << " in die Datei gespeichert" << endl; } File.close(); // Datei schließen } system("PAUSE"); return 0; } //---------------------------------------------------------------------------Kann mir jemand helfen???
-
Hallo
AnsiString::c_str() liefert dir doch schon einen Pointer, da brauchst du nicht extra die Adresse zu holen
File.write(Searchword[i].c_str(), len);bis bald
akari
-
Lass einfach das & vor Searchword weg. c_str() gibt dir ja schon ein const char*.
[edit]Heute bin ich wohl immer zu spät.
[edit]
-
Super Danke jetzt funktionierts!!!!!
Hab noch ne Frage zu dem '/0'...
Wieso muss das an das Ende des Strings angefügt werden bzw warum wird das nicht mit abgespeichert???und hier habe ich noch eine Frage:
if (File2.is_open()) { int len; int Size; File2.read((char*)&Size, sizeof(Size)); cout << "The Size of the Array is: "<<Size<<endl; String* Searchword = new String[Size+1]; for(int i=0;i < Size; i++) { File2.read((char*)&len, sizeof(len)); char* buffer = new char[len+1]; File2.read(buffer,len); buffer[len] = '\0'; Searchword[i] = buffer; delete[] buffer; cout << Searchword[i].c_str() << endl; } cout << Searchword[0].c_str(); <----- WARUM GEHT DAS } File2.close(); cout << Searchword[0].c_str();<------ DAS ABER NICHT?!MfG Straightflush
-
int len; int Size; fstream File2("List.dat", ios::in|ios::binary); if (File2.is_open()) { File2.read((char*)&Size, sizeof(Size)); cout << "The Size of the Array is: "<<Size<<endl; } String* Searchword = new String[Size+1]; if (File2.is_open()) { for(int i=0;i < Size; i++) { File2.read((char*)&len, sizeof(len)); char* buffer = new char[len+1]; File2.read(buffer,len); buffer[len] = '\0'; Searchword[i] = buffer; delete[] buffer; cout << Searchword[i].c_str() << endl; } cout << Searchword[0].c_str(); } File2.close(); cout << Searchword[0].c_str();so gehts!! gibts da noch ne elegantere lösung???
kann ich des irgendwie als global deklarieren??
-
Hallo
- "geht nicht" ist keine ausreichende Fehlerbeschreibung
- Rücke deinen Code vernünftig ein, um den lesbarer zu machen
- jedes Symbol muß in dem aktuellen Scope deklariert sein, um ihn zu benutzen. Deshalb ist klar, warum hier der Kompiler den Ausdruck nicht kenntif (...) { String* Searchword = new String[Size+1]; ... cout << Searchword[0].c_str(); // im richtigen Scope ... if (...) { cout << Searchword[0].c_str(); // immer noch im richtigen Scope } } cout << Searchword[0].c_str(); // nicht mehr im richtigen Scope, Kompiler kennt das nicht mehrdas sind aber alles Grundkenntnisse von C++, die du kennen solltest.
Wenn nicht, dann arbeite ein passendes Tutorial durch./Edit :
kann ich des irgendwie als global deklarieren??
Bitte nicht. Globale Variablen sollten nur wenn wirklich nötig verwendet werden.
Benutze Funktionsparameter und (statische) Klassenmember stattdessen.bis bald
akari
-
akari schrieb:
Benutze Funktionsparameter und (statische) Klassenmember stattdessen.
Was genau meinst du damit??
Das es in den richtigen Klammern sein muss habe ich inzwischen ja herausgefunden
-
Hallo
Was genau meinst du damit??
In einem konkreten Beispiel läßt sich das nicht umesetzen und ist auch nicht nötig. Es reicht wenn du innerhalb der Funktion die entsprechenden Variablen an der richtigen Stelle deklarierst,
Die von mir genannten Prinzipien brauchst du erst, wenn du Variablen bzw. deren Werte zwischen mehreren Funktionen austauschen willst.bis bald
akari
-
na jetzt hab ich ja die daten aus der datei herausgelesen und will nun ja auch noch was damit machen sonst hätte das ganze ja keinen zweck gehabt und deshalb wollte ich auch gerne wissen wie ich die variable für andere Funktionen bzw außerhalb der Funktion nutzen könnte...
-
Hallo
Mit den Prinzipien die ich genannt habe.
Arbeite das Tutorial durch, insbesondere den Abschnitt Funktionen.bis bald
akari
-
Hi,
Straightflush schrieb:
Hab noch ne Frage zu dem '/0'...
Wieso muss das an das Ende des Strings angefügt werden bzw warum wird das nicht mit abgespeichert???Ich schreib jetzt mal was ich über das mysteriöse '\0' weis.
char *zeichenkette;
zeichenkette ist ein char-Zeiger, der auf den Aanfang eines zusammenhängenden Speicherbereichs zeigt.
Das Ende des zusammenhängenden char-Zeiger Speicherbereich ist mit einem '\0' gekennzeichnet.char hallo[6]="arnold";
zeichenkette = hallo[0];
zeichenkette fängt bei hallo[0] an und geht bis zum '\0' oder hallo[6].Grüsse
-
Hallo,
Hier sind Fehler.
char hallo[6]="arnold";Dein char-Array hallo ist genau ein Zeichen zu kurz, weil das 0-Byte da ja auch noch rein muß. So wäre das besser.
const char* hallo = "arnold";Hier holt sich der Compiler die Länge (7) selbst. Außerdem ist die Variable jetzt korrekt ein const char* wie das Stringliteral ("arnold").
char* zeichenkette = hallo[0];Hier mußt du das [0] weglassen, da der Variablenname für den Pointer auf das erste Element steht und genau das müsstest du auch zuweisen. Allerdings sollte man derartige Zuweiseungen gar nicht machen. Immerhin steht in hallo ein const char*, was bedeutet, dass es nicht verändert werden darf. Du weist es einem char* zu, so das man später denken könnte, hier darf man was ändern. Die Maximallänge des Arrays kennst du dann auch nicht mehr. Lass sowas lieber. Besser wäre hier:
char* zeichenkette = new char[strlen(hallo)+1]; strcpy(zeichenkette,hallo); // irgendwelcher code und dann zum Schluß delete[] zeichenkette; // besser std::string zeichenkette = hallo;zeichenkette fängt bei hallo[0] an und geht bis zum '\0' oder hallo[6].
Ein char-Array endet (zumindest für die Stringfunktionen wie strlen, strcpy usw.) immer beim \0, egal wie groß das Array ist. Deswegen muß man hier aufpassen.
Ciao