Problem with gbinary files, and QVector
-
Hi, i tried to save QVector data, and read it from binary file, but it crashes every time, when i try to access the file.
If i remember good, it will work, but only if the QVector size is constant, then i can load it back, if i add some elements, save, and load the data, it will crash.
I think the problem is, i can't save the arrays correctly, because i get the whole one big object, cast it to char, and load it back. I tried to find some good tutorials, but i wasn't unable to save the all the data.
I use standard STD method, no qfile or something. If someone could give me an example or something, how to do it, i will appreciate it. If you want actual code, i will paste it here, but i don't think it will help, because most likely, it should be something completely different.
-
Hi,
It would surely help that you show the code you are using, otherwise it's just going to be shots in the dark as you don't explain what type of data you have in the QVector nor how you manipulate it.
-
Hi,
It would surely help that you show the code you are using, otherwise it's just going to be shots in the dark as you don't explain what type of data you have in the QVector nor how you manipulate it.
@SGaist
This is version one.#include "Windows/Main_Window/Main_Window.hpp" #include "ui_Main_Window.h" #include <QDebug> //*************************************************************************** //*************************************************************************** Main_Window::Main_Window(QWidget *parent) : QMainWindow(parent), ui(new Ui::Main_Window) { ui->setupUi(this); this->file_I = new ifstream("Data.bin", ios_base::binary | ios_base::in | ios_base::trunc); this->file_O = new ofstream; } //*************************************************************************** //*************************************************************************** Main_Window::~Main_Window() { this->file_I->close(); this->file_O->close(); delete this->file_I; delete this->file_O; delete ui; } //*************************************************************************** //*************************************************************************** void Main_Window::on_save_button_clicked() { this->Get_Data(); this->Write(this->File, this->data); this->Show_Data(); } //*************************************************************************** //*************************************************************************** void Main_Window::on_load_button_clicked() { this->Load(this->File, this->data); this->Show_Data(); } //*************************************************************************** //*************************************************************************** void Main_Window::Write(FILE* file, Data& data) { file = fopen("Data.bin", "wb"); fwrite(&data, sizeof(Data), 1, file); fclose(file); } //*************************************************************************** //*************************************************************************** void Main_Window::Load(FILE* file, Data& data) { fopen("Data.bin", "wb"); fread(&data, sizeof(Data), 1, file); fclose(file); } //*************************************************************************** //*************************************************************************** void Main_Window::Show_Data() { this->ui->table_widget->item(0, 0)->setText(QString::number(this->data.scatter)); this->ui->table_widget->item(1, 0)->setText(QString::number(this->data.speed)); this->ui->table_widget->item(2, 0)->setText(QString::fromStdString(this->data.name)); } //*************************************************************************** //*************************************************************************** void Main_Window::Get_Data() { this->data.scatter = this->ui->table_widget->item(0, 0)->text().toInt(); this->data.speed = this->ui->table_widget->item(1, 0)->text().toInt(); this->data.name = this->ui->table_widget->item(2, 0)->text().toStdString(); } //*************************************************************************** //***************************************************************************
-
Hi,
It would surely help that you show the code you are using, otherwise it's just going to be shots in the dark as you don't explain what type of data you have in the QVector nor how you manipulate it.
@SGaist
I tried many times, and this crap still don't work.
``#include "Windows/Main_Window/Main_Window.hpp" #include "ui_Main_Window.h" #include <QDebug> //*************************************************************************** //*************************************************************************** Main_Window::Main_Window(QWidget *parent) : QMainWindow(parent), ui(new Ui::Main_Window) { ui->setupUi(this); this->file_I = new ifstream("Data.bin", ios_base::binary | ios_base::in | ios_base::trunc); this->file_O = new ofstream; } //*************************************************************************** //*************************************************************************** Main_Window::~Main_Window() { this->file_I->close(); this->file_O->close(); delete this->file_I; delete this->file_O; delete ui; } //*************************************************************************** //*************************************************************************** void Main_Window::on_save_button_clicked() { this->Get_Data(); this->Write((*this->file_O), this->data); this->Show_Data(); } //*************************************************************************** //*************************************************************************** void Main_Window::on_load_button_clicked() { this->Load((*this->file_I), this->data); this->Show_Data(); } //*************************************************************************** //*************************************************************************** void Main_Window::Write(ofstream &file, Data& data) { file.open("Data.bin", ios_base::binary | ios_base::out | ios_base::trunc); if(file.is_open() == true) { file.write((char*)&data, sizeof(Data)); } file.close(); } //*************************************************************************** //*************************************************************************** void Main_Window::Load(ifstream &file, Data& data) { file.open("Data.bin", ios_base::binary | ios_base::in | ios_base::trunc); if(file.is_open() == true) { while(!file.eof()) {file.read((char*)&data, sizeof(Data));} } file.close(); } //*************************************************************************** //*************************************************************************** void Main_Window::Show_Data() { this->ui->table_widget->item(0, 0)->setText(QString::number(this->data.scatter)); this->ui->table_widget->item(1, 0)->setText(QString::number(this->data.speed)); this->ui->table_widget->item(2, 0)->setText(QString::fromStdString(this->data.name)); } //*************************************************************************** //*************************************************************************** void Main_Window::Get_Data() { this->data.scatter = this->ui->table_widget->item(0, 0)->text().toInt(); this->data.speed = this->ui->table_widget->item(1, 0)->text().toInt(); this->data.name = this->ui->table_widget->item(2, 0)->text().toStdString(); } //*************************************************************************** //***************************************************************************
-
By looking at the code are you writing the Data(which is structure/class) to file ? While writing the user defined objects you need to serialise & write it. Have you seen the [example] ?(http://blog.qt.io/blog/2018/05/31/serialization-in-and-with-qt/). Also I did not see Vector in the code. Did I miss something ?
-
By looking at the code are you writing the Data(which is structure/class) to file ? While writing the user defined objects you need to serialise & write it. Have you seen the [example] ?(http://blog.qt.io/blog/2018/05/31/serialization-in-and-with-qt/). Also I did not see Vector in the code. Did I miss something ?
@dheerendra I notice the problem with saving any data. I can save something, but if i close the program and run it again, then try to read it, the program will always crash.
I saw many of tutorials, but they are a little bit stupid, what they do, they save the file, and read it immediately, they don't close the program. -
When it's crashing you should use a debugger to see where exactly it is crashing. And since we're a Qt forum I would not use std::io but QFile.
-
When it's crashing you should use a debugger to see where exactly it is crashing. And since we're a Qt forum I would not use std::io but QFile.
@Christian-Ehrlicher I tried that too, but it won't help. It will be good, is someone could take a look at the load function, because i feel like it's not loading the data correctly.
-
First you open the file twice. Second I don't understand why you pass all ifstream and ofstream around around for no good reason. And Third I don't think you want to read a file which gets truncated when it's opened for reading.
You should really use a debugger to see where it crashes as I already said in my last post - I don't see what your problem has to do why Qt in any way. -
First you open the file twice. Second I don't understand why you pass all ifstream and ofstream around around for no good reason. And Third I don't think you want to read a file which gets truncated when it's opened for reading.
You should really use a debugger to see where it crashes as I already said in my last post - I don't see what your problem has to do why Qt in any way.@Christian-Ehrlicher Listen, if i was good with files, i would not ask for help most likely, this is just a test program and it has nothing to do with real data, and real functionality.
I tried it with the second version of the code, that one with ofstream and ifstream, and now it's not crashing but it loads the default values... I have no clue why, it's working like there is no load function, and the data is not loading.
So i am running the program, i change the values and save them, exit, then i run it again, click the load button, and i see the default values.
-
@Christian-Ehrlicher said in Problem with gbinary files, and QVector:
I don't think you want to read a file which gets truncated when it's opened for reading.
Did you actually read what ios_base::trunc does?
-
@Christian-Ehrlicher said in Problem with gbinary files, and QVector:
I don't think you want to read a file which gets truncated when it's opened for reading.
Did you actually read what ios_base::trunc does?
@Christian-Ehrlicher I remember i tried not using it, and it dosn't help.
-
You're truncating your file both when reading and writing. Then you have that
data
variable but it's unknown whether it's properly initialised. -
You're truncating your file both when reading and writing. Then you have that
data
variable but it's unknown whether it's properly initialised.@SGaist Ok, i try again, but take in consideration in those tutorials i saw, they use that trunc.
I removed that trunc everywhere, now something is working, but the next problem i get, is it's crashing, because of the string "name" variable.
What happened, is i get the error, i run the debugger, and it points on the name variable, in the show_data function, if i just comment it, then it's working.How to fix this? I guess it's the stream size fault, because last day i saw a weird error, and saw some weird symbols when i was trying to read the data, and the program crash few seconds later.
How to save all those QVectors, stings etc, when the size variable change?
-
I do take that into consideration. You should also take into consideration that if there's something you are not sure about, you should look up the documentation regarding that element rather than blindingly adding things here and there.
As suggested before, since you are using Qt, use its facilities like QFile and QDataStream and be done with it. Streaming of QString, QVector etc, is already supported.
-
I do take that into consideration. You should also take into consideration that if there's something you are not sure about, you should look up the documentation regarding that element rather than blindingly adding things here and there.
As suggested before, since you are using Qt, use its facilities like QFile and QDataStream and be done with it. Streaming of QString, QVector etc, is already supported.
-
@SGaist I don't know any documentation about files and arrays, if i was able to do it with that, i would not post anything, because there is no point.
@Loc888 The link to QDataStream that @SGaist gave you contains an almost reusable, yet small example for loading and saving. Have you looked at it?
Regards
-
@SGaist Ok, i try again, but take in consideration in those tutorials i saw, they use that trunc.
I removed that trunc everywhere, now something is working, but the next problem i get, is it's crashing, because of the string "name" variable.
What happened, is i get the error, i run the debugger, and it points on the name variable, in the show_data function, if i just comment it, then it's working.How to fix this? I guess it's the stream size fault, because last day i saw a weird error, and saw some weird symbols when i was trying to read the data, and the program crash few seconds later.
How to save all those QVectors, stings etc, when the size variable change?
@Loc888
Hi
The real benefit of using QFile and QDataStream is that it already can handle many Qt types.
(including QString and QVector)http://doc.qt.io/qt-5/datastreamformat.html
So you need not to do anything special besides how mini sample shows it
QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file); // we will serialize the data into the file
QVector<double> list;
out << list; // serialize a list of doubles. handle size by it self.However, if you QVector is a list of custom object ( your own class) you need to define
<< and >> for it so it know how to stream your types too.
Often that is just to stream the member variables if they in turn are plain Qt types. -
@Loc888
Hi
The real benefit of using QFile and QDataStream is that it already can handle many Qt types.
(including QString and QVector)http://doc.qt.io/qt-5/datastreamformat.html
So you need not to do anything special besides how mini sample shows it
QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file); // we will serialize the data into the file
QVector<double> list;
out << list; // serialize a list of doubles. handle size by it self.However, if you QVector is a list of custom object ( your own class) you need to define
<< and >> for it so it know how to stream your types too.
Often that is just to stream the member variables if they in turn are plain Qt types.@mrjj Ok, i tried it with simple data, and it's working very good, it's even too easy to use, with comparision to that std stuff. So, about that standard method, if someone could help me learn how to do that, i mean how to read an array i will appreciate it, even if i am gonna use QFile because it's much more cleaner and faster too use.
-
@mrjj Ok, i tried it with simple data, and it's working very good, it's even too easy to use, with comparision to that std stuff. So, about that standard method, if someone could help me learn how to do that, i mean how to read an array i will appreciate it, even if i am gonna use QFile because it's much more cleaner and faster too use.
@Loc888
Hi
yes, its actually nicer than the std stuff.Well, it can directly do it with QVector.
It actually write the size first then each item but its handled automatically.When you say array, you mean QVector or what type ?
for any supported Qtype, a list or vector is the same as basic variables.
simply
outstream << thelist;
and
instream >> somelistvar;Do you have a special case in in mind with the "array" ?
Can you show the declaration of your array ?
makes it easier to talk about.