FileStream und binary mode
-
hi!
Ich wollte meine Daten im binärmodus speicher...
leider komm ich grad net so sehr zurecht damit..ich hab ein tut gefunden:
http://209.85.129.104/search?q=cache:lQsrYRnCTWgJ:www.fachinformatiker-ihk.de/download/extras/Fh_mit_BCB.pdf+c%2B%2B+borland+binary+schreiben&hl=de&ct=clnk&cd=1&gl=de
Seite 6.
Ich hab mir also eine Strucktur geschrieben die meine Daten enthalten soll...hab es auch wchar_t gemacht, oder geht auch String???
ich hab Probleme beim umwandeln:
Ich habe einige Daten im String format vorliegen. wie bekomme ich das in WideChar umgewandelt ohne das mir was vom inhalt verloren geht?
der String kann so lang sein wie der user möchte.
Zudem muss ich das ganze dann wieder rückwandeln können wenn ich es einlese, also von wchar_t zu String...
wie mach ich das am besten?Danke schonamal für die Hilfe
-
Ich habs jetzt so gemacht:
struct TMeineDaten { wchar_t Zusatz; wchar_t Name; wchar_t Vorname; wchar_t Bemerkung; }
und im code wo ich dann jede eingetragene zeile speichere:
String Zusatz="Test"; fstream outStream(Pfad.c_str(),ios::binary|ios::out); for(int i=0;i<Datenanzahl;i++) { TMeineDaten Daten; int l; l = Zusatz.WideCharBufSize(); Zusatz.WideChar(Daten.Zusatz,l); l = EditUsername->Text.WideCharBufSize(); EditUsername->Text.WideChar(Daten.Name,l); usw...
da kommt der fehler:
Cannot convert 'int' to 'wchar_t *' Type mismath in parameter 'dest'(want 'wchar_t *',got 'wchar_t')
Was is da falsch?? :<
hier würde ich dann jede zeile in der schleife schreiben:
outStream.write((char*)&Daten,sizeof(TMeineDaten));
Warum kommt aber obens chon der fehler?? -.-
-
Ein wchar_t enthält nur ein einzelnes Zeichen. Du bräuchtest hier schon ein Array (natürlich initialisiert).
Warum willst du eigentlich WideChars verwenden? Außerdem gibt es ja noch WideString.
-
Er will einen AnsiString binärsicher schreiben und wieder einlesen, geht um den mit blowfish verschlüsselte binäre AnsiString.
@Puccini
Das Schreiben war schon O.K. so, wenn ich das richtig sehe. Problem war das Einlesen eines binären Stringes mit getline, wenn dort zufällig ein std::endl in dem verschlüsselten String auftaucht.
-
witte schrieb:
Er will einen AnsiString binärsicher schreiben und wieder einlesen, geht um den mit blowfish verschlüsselte binäre AnsiString.
Auch dafür macht wchar_t keinen Sinn. unsigned char reicht völlig aus.
-
Braunstein schrieb:
Auch dafür macht wchar_t keinen Sinn. unsigned char reicht völlig aus.
Hat ja auch kein Mensch behauptet, dass er wchar_t nehmen soll. Er soll sich um das Einlesen kümmern.
-
hi,
ich hab das jetzt nochmals umgeschrieben, da widechar wirkich quatsch war XD
Jetzt hab ichs so:
Schreiben:
String Username = EditUsername->Text.c_str(); int Lang = Username.Length(); outStream.write((const char*)&Lang,sizeof(Lang)); char *buffer = new char(Lang); buffer=NULL; buffer = Username.c_str(); outStream.write((const char*)&buffer,Lang);
Lesen:
String Username; int Lang; char *buffer; inStream.read((char*)&Lang,sizeof(Lang)); buffer=new char(Lang); buffer=NULL; inStream.read((char*)&buffer,Lang); Username=buffer;
Funktioniert nicht so richtig.. warum?? :<
ich lass mir den String dann noch ausgeben, und da ist er das erste mal leer und wenn ich nochmal auf den Button laden drücke, steht auf einmal was drin -.-gibts noch einen besseren weg?
Ich will auch die integerwerte der buchstaben speichern, doch die tauchen dann in der datei wieder als buchtaben auf!Symbol=int(Username[k]); outStream.write((const char*)&Symbol,sizeof(Symbol));
damit sollen die Usernamen nicht im klartext in der datei stehen, sondern halt als integerwerte XD.
liegt das am const char und char??
-
Schau Dir mal als "Referenz" diesen Code an:
void __fastcall TForm1::btnEncryptClick(TObject *Sender) { String msg = "test"; String key = "test"; TBlowfish b1((unsigned char *)key.c_str(), key.Length()); b1.Encrypt(&msg); fstream ofs("C:\\temp\\msg.dat", ios::binary | ios::out); ofs << msg.Length() << msg; } //--------------------------------------------------------------------------- void __fastcall TForm1::btnDecryptClick(TObject *Sender) { String key = "test"; int Length; fstream ifs("C:\\temp\\msg.dat", ios::binary | ios::in); ifs >> Length; unsigned char *buffer = new unsigned char[Length]; ifs.read(buffer, Length); TBlowfish b1((unsigned char *)key.c_str(), key.Length()); String msg = (char*)buffer; delete[] buffer; b1.Decrypt(msg); } //---------------------------------------------------------------------------
Fang von dort an und pass es Dir an. Da fehlt aber noch die Fehlerbehandlung und es sollte sichergestellt sein dass das delete[] immer aufgerufen wird.
-
der meckert mich an das "AnsiString" nicht implementiert ist für den operator << im typ ostream...
bei der zeile:
outStream<<msg.Length()<<msg;kann ich da einfach schreiben:
outStream<<msg.Length()<<msg.c_str();
oder wird dabei der Blowfish-string zerstört??
-
Setz das Symbol VCL_IOSTREAM in Projekt=>Optionen=>Verzeichnisse/Bedingungen=>Bedingungen=>Definition
-
ich hab ein Problem...
Ich hab nen String:
msg=100ABCDEF
als beispiel..
wenn ich dann schreibe:outStream<<msg.Length()<<msg;
und mir die länge ausgeben lasse mit ShowMessage(msg.Length());
dann steht da 9, wies sein sollte.
diese Zahl steht auch in der Datei.
Da steht:
9100ABCDEFWenn ich die datei jetzt auslese mit:
inStream>>Lang;
ist Lang auf einmal 9100
warum das -.-
ich dachte wenn ich binär speicher wäre das nicht der fall... ich dachte da sieht man die zahlen nicht in der datei. :<
wie muss ich das nun machen ?
-.- bin zu doof für sowas
-
Hallo
Was erwartest du? Du must einlesen wie du gespeicherst hast. Also erstmal die Länge der Zeichenkette, dann die Zeichenkette selber. Da hast du nun aber ein Problem : Die Länge der Zeichenkette speicherst du nicht binär, was zur Folge hat das diese in der Datei eine variable Länge hat und nicht mehr von der eigentlichen Zeichenkette getrennt werden kann.
Korrekt sollte es zum Beispiel so aussehen :
// speichern AnsiString msg = "..."; unsigned int length = msg.Length(); outStream << reinterpret_cast<const char*>(length); // Der Wert in length wird in genau 4 Bytes gespeichert outStream << msg.c_str(); // Die Zeichenkette wird gespeichert // einlesen unsigned int length; char* buffer = new char[length +4]; inStream.read(4, buffer; // Es werden genau 4 Byte ausgelesen length = reinterpret_cast<unsigned int>(*buffer); // Umwandlung in korrekten Integer delete buffer; buffer = new char[length +1]; // Zwischenspeicher zum Einlesen inStream.read(length, buffer); buffer[length] = 0; AnsiString msg = buffer; delete buffer;
bis bald
akari/Edit : Code korrigiert
-
ich bekommen immer einen access violation fehler wenn ich versuche meine datei zu speichern:
String Pfad= Form1->Pfad.c_str(); Form1->lastPfad=Pfad; Form1->aktiverPfad->Caption=Form1->lastPfad; fstream outStream(Pfad.c_str(),ios::binary|ios::out); try{ String key = EditPasswort->Text; TBlowfish c1((unsigned char *)key.c_str(), key.Length()); String MD5Key = getMD5(key); unsigned int ULang; ULang=MD5Key.Length(); outStream<<reinterpret_cast<const char*>(ULang); ShowMessage(ULang); outStream<<MD5Key.c_str();
ShowMessage wir schon nicht mehr angezeigt, da beim schreiben des integers ein fehler auftritt......
-
Hallo
Ah noch ein Fehler in meinem Code...
Das speichern der Längenangabe muß natürlich auch byteweise und nicht mit Stream-Operator passierenoutStream.write(4, reinterpret_cast<const char*>(ULang));
bis bald
akari
-
also so hier??
outStream.write(reinterpret_cast<const char*>(ULang),4); outStream<<msg.c_str();
oder so:
outStream.write(reinterpret_cast<const char*>(ULang),4); outStream.write(msg.c_str(),ULang);
Ibeiden fällen bleibt die Datei 0 Byte gross, also wird nix geschrieben!
-.-
wo is den da schon wieder der fehler :<
ich geh hier nochmal fest. is es wirklich so schwer binär in eine datei zu speichern? :<edit:
outStream.write(reinterpret_cast<const char*>(&ULang),4); outStream.write(MD5Key.c_str(),ULang);
So wird was in die Datei geschrieben!
String UN= Form1->EditUsername[i]->Text.c_str(); ULang=UN.Length(); outStream.write(reinterpret_cast<const char*>(&ULang),4); for(int k=0;k<ULang;k++) { Symbol=int(UN[k+1]); outStream.write(reinterpret_cast<const char*>(&Symbol),4); }
warum wird hier nicht die Zahl sonder wieder der buchstabe in die Datei geschrieben?ß :<
ich will ja grade dasman nicht den text lesen kann -.-ich hab hier noch was gefunden
würde das gehen? oder wegen den ganzen sonderzeichem im blowfish auch net?? :<
http://www.bytesandmore.de/rad/index.htm?http://www.bytesandmore.de/rad/cpp/snipp/sc01007.php
-
akari, du kennst dich doch damit supi aus odr??
könnte ich dir mal ein Projekt schicken und du schaust dir das mal an warum das net funktioniert?? :>
ich bin hier am verzeifeln.. nichts, kein einzieges tut hilft mir -.-
also muss ich mich ja irgendwie doof anstellen, wenns bei anderen geht :<
-
Hallo
Also nochmal zusammengefasst und getestet
// Speichern AnsiString test = "Das ist ein Test"; unsigned int length = test.Length(); ofstream of("test.dat", ios::binary|ios::out); of.write(reinterpret_cast<char*>(&length), 4); // Hier hat noch der &-Operator gefehlt of.write(test.c_str(), length); // Laden char* buffer = new char[4]; ifstream of("test.dat", ios::binary|ios::in); of.read(buffer, 4); int length = *(reinterpret_cast<int*>(buffer)); // Hier muß in Pointer gecastet werden delete[] buffer; buffer = new char[length +1]; of.read(buffer, length); buffer[length] = 0; AnsiString test = buffer; delete[] buffer;
warum wird hier nicht die Zahl sonder wieder der buchstabe in die Datei geschrieben?
Natürlich werden Zahlen in die Dateien geschrieben, Computer arbeiten intern ausschließlich mit Zahlen. Die Datei besteht aus den ASCII-Codes der Zeichen. Wenn du die Datei in einem Editor ausmachst interpretiert dieser natürlich die Zahlen wieder als Zeichen. Das ist trotzdem korrektes binäres Speichern von Zeichenketten. Wenn du die Zeichenkette ganz unlesbar machen willst must du sie verschlüsseln.
bis bald
akari
-
oh man, jetzt gehts
danke dir nochmals 1000mal für die hilfe
ich hoffe das jett wirklich keine fehler mehr kommen -.-..aber das war jetzt ne harte nuss XD
hoffe es hilft auch anderen weiter, was du hier an arbeit geleistet hast
-
Da ist immer noch ein Fehler drin.
Puccini, ist das der mit Blowfish verschlüsselte String, den Du wieder einlesen willst? Dann wird Zeile 17 nicht laufen, wenn zufällig ein '\0' in dem String steht.AnsiString msg = AnsiString(buffer, Length);
-
genau der is es..
also muss ich zeile 17 mit deiner austauschen, dann gehts??