Russian Qt Forum

Qt => Общие вопросы => Тема начата: merke от Ноябрь 16, 2010, 06:49



Название: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 06:49
Всем привет!

Допустим у меня есть структура:

Код:
struct dec_struct
{
   QByteArray n1;//Размер будет 4 байта
   QByteArray n2;//Размер будет 6 байтов
   int x;
   int y;
}my_str;

Теперь мне необходимо создать массив данной структуры:
Код:
QList<dec_struct> lst;

Так теперь наполняю её вот так:

Код:
my_str.n1 = "1234";
my_str.n2 = "123456";
my_str.x  =  3;
my_str.y  =  4;

Помещаю всё это в массив данной структуры в нулевой элемент.

Код:
lst.append(my_str);
Вот а теперь вопрос: Как мне корректно записать данный массив в файл.

Пробовал такое

Код:
QFile file("test.dat");
file.open(QIODevice::WriteOnly|QIODevice::Append);
QDataStream stream(&file);
for (int i = 0;i<lst.count();i++)
  stream << lst[i];

Но при записи записи вместо 18 байтов(именно такой размер имеет моя тестовая структура) записывается на 8 байт больше. Я так понимаю записывается 4 байта от QDataStream, ну это ладно понятно, а откуда ещё 4 байта?

Смотрите в чем дело, мне нужно записать в файл четко именно 18 байт. Как мне отказаться от QDataStream чтобы не дописывать ещё лишние 4 байта в начале, также как мне по другому записать мою структуру в файл, чтобы её аналогичным потом способом можно было считать обратно.

Буду благодарен помощи!

С уважением, Александр!



Название: Re: Запись структуры в файл
Отправлено: Пантер от Ноябрь 16, 2010, 08:20
Напиши функцию QDataStream & operator<< ( QDataStream & out, const dec_struct & s ) и сможешь делать stream << my_str.


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 08:27
уже сделал такое   
Код:
   friend QDataStream &operator<<(QDataStream & ds,  dec_struct &calData)
    {
        ds << calData.n1 << calData.n2 << calData.x << calData.y;
        return ds;
    }
    friend QDataStream &operator>>(QDataStream & ds, dec_struct &calData)
    {
        ds >> calData.n1 >> calData.n2 >> calData.x >> calData.y;
        return ds;
    }
Но при записи такого как раз таки и добавляются левые 8 байтов ???


Название: Re: Запись структуры в файл
Отправлено: BRE от Ноябрь 16, 2010, 09:12
Но при записи такого как раз таки и добавляются левые 8 байтов ???
8 "левых" байт пишут два QByteArray. В этих байтах сохраняется длина каждого массива (int32). Нужна эта длина, чтобы корректно прочитать эти массивы из файла.


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 09:22
Код:
struct dec_struct
{
   char  n1[4];//Размер будет 4 байта
   char n2[6];//Размер будет 6 байтов
   int x;
   int y;
}my_str;
а если я изменю вот так структуру

То как теперь переопределить операторы >> <<?

как записать теперь такую структуру?

а то выдается ошибка:

no match for ‘operator>>’ in ‘ds >> & calData->MainWindow::my_struct::fam’


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 10:10
Делаю так:


Код:
    struct my_struct
    {
        char *name;
        int age;
        char *fam;
        int nomer;
    }m_str;

потом так:

 
Код:
   m_str.age = 2;
    m_str.nomer = 4;
    m_str.name = "alex";
    m_str.fam = "zub";

    lst.append(m_str);
   

Код:
    QFile file("test.dat");
    file.open(QIODevice::WriteOnly|QIODevice::Append);
    QDataStream stream(&file);
    stream << lst[0];

Код:
friend QDataStream &operator<<(QDataStream & ds, const my_struct &calData)
    {
        ds.writeRawData((char*)calData.fam, 8);
        ds.writeRawData((char*)calData.name,8);

        ds << calData.age << calData.nomer;
        return ds;
    }
    friend QDataStream &operator>>(QDataStream & ds, my_struct &calData)
    {
        ds.readRawData((char*)calData.fam, 8);
        ds.readRawData((char*)calData.name,8);
        ds >> calData.age >> calData.nomer;
        return ds;
    }

А вот так считываю:

Код:
    QFile file("test.dat");
    file.open(QIODevice::ReadOnly);
    QDataStream in(&file);
    in >> m_str;
    qDebug() << m_str.name << m_str.fam << m_str.age << m_str.nomer;

Так вот при чтении прога просто закрывается и всё. без каких либо ошибок

В чем может быть проблема?


Название: Re: Запись структуры в файл
Отправлено: Пантер от Ноябрь 16, 2010, 10:14
calData.fam = new char забыл. И с name то же самое.


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 10:26
А если не использовать вообще указатели?


Название: Re: Запись структуры в файл
Отправлено: Пантер от Ноябрь 16, 2010, 10:28
Ну дык char  n1[4] используй.


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 11:40
Сделал так.

теперь тока считать корректно не получается.

Пожалуйста, очень прошу, помогите записать структуру вида

Код:
  struct my_struct
    {
        char name[8];
        char fam[8];
        int nomer;
        int age;
    }m_str;

в файл и также считать её от туда.

Буду очень благодарен! Просто мне это очень нужно. Голова пухнет


Название: Re: Запись структуры в файл
Отправлено: Пантер от Ноябрь 16, 2010, 11:45
Давай сюда минимальный компилябельный пример. Что именно не считывает?


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 12:04
вот исходник.

Считывается не то что было записано. Не вся информация.


Название: Re: Запись структуры в файл
Отправлено: Пантер от Ноябрь 16, 2010, 12:22
Код
C++ (Qt)
char name[9];
char fam[9];
 
Для strcpy на один символ больше, туда заносится '\0'.
Все отлично работает.


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 12:57
Спасибо Большое!!!

А вот лучше наверное будет отказаться от всех QString в проекте и перейти к char. Потому что в основном работа будет с самопальной базой данных. И нужно что писалось ровно столько байт сколько имеется, ни какой служебной инфы как
это делает QString и QByteArray.

Я вот конвертацию с QString в char* делаю следующим образом:

Код:
QString str1 = "Test";
QByteArray ba = str1.toLatin1();
const char *c_str2 = ba.data();

Вопрос что значит const в этой записи? вот самый банальный вопрос самому стыдно.
И ещё как теперь сделать обратную конвертацию т.е. в QString?


Название: Re: Запись структуры в файл
Отправлено: Пантер от Ноябрь 16, 2010, 13:11
const означает, что ты c_str2 не сможешь изменить.
Обратно QString ( const char * str ).


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 13:15
Спасибо!

Вы очень меня сегодян выручаете! Очень вам благодарен!!!

Ещё вопрос:

Код:
strcpy(m_str.name,  "alexalex");

Как можно по другому внести значение в m_str.name только чтобы в конец не добавлялся /0 ?


Название: Re: Запись структуры в файл
Отправлено: Пантер от Ноябрь 16, 2010, 13:19
Не. name и должен быть на один символ больше. строка char должна заканчиваться на '\0', иначе можно выйти за ее пределы.


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 13:23
Просто в рамках ТЗ там описана структура например

имя файла строковая переменная - 8 байт
дата изменения строковая перменная - 10 байт

и т.д.

и мне нужно что именно было в файл записано 18 байт и ни на один больше ни на один меньше. Вот к чему я все веду.


Название: Re: Запись структуры в файл
Отправлено: Пантер от Ноябрь 16, 2010, 13:26
Так у тебя и записывается правильно.
char c [4] = "123\0" в файл запишется как 3 байта. Т.е. все нормально.


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 13:34
Ну вот смотрите скидываю вам опять исходник, гляньте плиз. Может я опять что то намудрил, но у меня вместо 24 байт пишется 26 байт.



Название: Re: Запись структуры в файл
Отправлено: Пантер от Ноябрь 16, 2010, 13:40
ds.writeRawData((char*)calData.fam,sizeof(calData.fam)); замени на
ds.writeRawData((char*)calData.fam,8);


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 13:47
заменил на 8 и теперь записывается конечно же 24 байта, считывается какая то белибирдистика alexalex†famafama¿ famafama¿ 8 4


Название: Re: Запись структуры в файл
Отправлено: Пантер от Ноябрь 16, 2010, 13:51
Код
C++ (Qt)
friend QDataStream &operator<<(QDataStream & ds, const my_struct &calData)
{
ds.writeRawData((char*)calData.fam, 8);
ds.writeRawData((char*)calData.name, 8);
 
ds << calData.age << calData.nomer;
return ds;
}
friend QDataStream &operator>>(QDataStream & ds, my_struct &calData)
{
ds.readRawData((char*)calData.fam, 8);
calData.fam [8] = '\0';
ds.readRawData((char*)calData.name, 8);
calData.fam [8] = '\0';
ds >> calData.age >> calData.nomer;
return ds;
}
 


Название: Re: Запись структуры в файл
Отправлено: merke от Ноябрь 16, 2010, 14:04
Во супер! Сппасибо! Низкий паклон Вам!!!