Russian Qt Forum
Ноябрь 26, 2024, 01:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Запись структуры в файл  (Прочитано 14953 раз)
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 байта в начале, также как мне по другому записать мою структуру в файл, чтобы её аналогичным потом способом можно было считать обратно.

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

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

« Последнее редактирование: Ноябрь 16, 2010, 06:52 от Александр » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Ноябрь 16, 2010, 08:20 »

Напиши функцию QDataStream & operator<< ( QDataStream & out, const dec_struct & s ) и сможешь делать stream << my_str.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
merke
Гость
« Ответ #2 : Ноябрь 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 байтов Непонимающий
Записан
BRE
Гость
« Ответ #3 : Ноябрь 16, 2010, 09:12 »

Но при записи такого как раз таки и добавляются левые 8 байтов Непонимающий
8 "левых" байт пишут два QByteArray. В этих байтах сохраняется длина каждого массива (int32). Нужна эта длина, чтобы корректно прочитать эти массивы из файла.
Записан
merke
Гость
« Ответ #4 : Ноябрь 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’
« Последнее редактирование: Ноябрь 16, 2010, 09:26 от Александр » Записан
merke
Гость
« Ответ #5 : Ноябрь 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;

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

В чем может быть проблема?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #6 : Ноябрь 16, 2010, 10:14 »

calData.fam = new char забыл. И с name то же самое.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
merke
Гость
« Ответ #7 : Ноябрь 16, 2010, 10:26 »

А если не использовать вообще указатели?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #8 : Ноябрь 16, 2010, 10:28 »

Ну дык char  n1[4] используй.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
merke
Гость
« Ответ #9 : Ноябрь 16, 2010, 11:40 »

Сделал так.

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

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

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

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

Буду очень благодарен! Просто мне это очень нужно. Голова пухнет
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #10 : Ноябрь 16, 2010, 11:45 »

Давай сюда минимальный компилябельный пример. Что именно не считывает?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
merke
Гость
« Ответ #11 : Ноябрь 16, 2010, 12:04 »

вот исходник.

Считывается не то что было записано. Не вся информация.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #12 : Ноябрь 16, 2010, 12:22 »

Код
C++ (Qt)
char name[9];
char fam[9];
 
Для strcpy на один символ больше, туда заносится '\0'.
Все отлично работает.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
merke
Гость
« Ответ #13 : Ноябрь 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?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #14 : Ноябрь 16, 2010, 13:11 »

const означает, что ты c_str2 не сможешь изменить.
Обратно QString ( const char * str ).
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.077 секунд. Запросов: 22.