Cześć,
Mam w programie u siebie mapę przechowującą liczbę arabską jako klucz (int) i liczbę rzymską jako wartość (QString):
QMap<int,QString> ArabRzym;
Zawartość tej mapy chcę zapisać na dysku w pliku w postaci binarnej, używając podstawowej klasy std::fstream. Nie chcę używać klasy QFile, czy innej klasy z Qt, gdyż chcę się nauczyć uniwersalnej obsługi plików w C++ za pomocą biblioteki standardowej.
Oczywiście nie można zapisać sobie obiektu klasy QString w ten sposób...
// plik to obiekt klasy std::fstream
plik.write((char*)&lancuch,sizeof(QString));
...gdyż nic nie wiadomo o jego długości co może być problemem przy odczycie pliku i główną przyczyną segfaultów, bo jak wiadomo podczas odczytu łańcuchy mogą być różnej długości, a nie sizeof(QString).
Napisałem więc takie slociki do zapisu oraz do odczytu danych:
Zapis:
void OknoGlowne::zapisz(){
std::fstream plik("liczby.dat",std::ios::out|std::ios::binary);
if(plik.is_open()){
// Zapisanie ilości danych w mapie.
int ilosc=this->ArabRzym.count();
plik.write((char*)&ilosc,sizeof(int));
int ar, dlRz; QString rz;
for(QMap<int,QString>::Iterator it=this->ArabRzym.begin();it!=this->ArabRzym.end();++it){
ar=it.key(); rz=it.value(); dlRz=rz.length();
// Zapisanie liczby arabskiej i długości łancucha liczby rzymskiej.
plik.write((char*)&ar,sizeof(int));
plik.write((char*)&dlRz,sizeof(int));
// Zapisanie liczby rzymskiej znak po znaku.
QChar temp;
for(int i=0;i<dlRz;i++){
temp=rz[i];
plik.write((char*)&temp,sizeof(QChar));
}
}
plik.close();
}
}
Odczyt:
void OknoGlowne::odczytaj(){
this->ArabRzym.clear();
std::fstream plik("liczby.dat",std::ios::in|std::ios::binary);
if(plik.is_open()){
// Odczytanie ilości danych dla mapy.
int ilosc;
plik.read((char*)&ilosc,sizeof(int));
int ar, dlRz; QString rz;
for(int i=0;i<ilosc;i++){
// Odczytanie liczby arabskiej i długości łancucha liczby rzymskiej.
plik.read((char*)&ar,sizeof(int));
plik.read((char*)&dlRz,sizeof(int));
// Odczytanie liczby rzymskiej znak po znaku.
QChar temp;
for(int j=0;j<dlRz;j++){
plik.read((char*)&temp,sizeof(QChar));
rz.append(temp);
}
this->ArabRzym.insert(ar,rz);
rz.clear();
}
plik.close();
// Jakaś funkcja do wypełniania tabeli w programie
this->wypelnij();
}
}
Moje pytanie: Czy za pomocą samej tylko klasy std::fstream da się 'ładniej' zapisać do pliku binarnego obiekt klasy QString?
Obecny format pliku z danymi:
ilość danych | (liczba arabska | długość łańcucha liczby rzymskiej | łańcuch liczby rzymskiej) * ilość danych
Pozdrawiam
Grzesiek
rz.toStdString().length();
grzesiek51114grzesiek51114