Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
1

Сохранение значения структуры после перезапуска

25.10.2015, 15:19. Показов 1243. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день. Посоветуйте плиз, такой вопрос
Имеется структура, одному члену которой (тип String) присваивается значение по кнопке.
Структура вида
C++
1
2
3
pr.A[atoi(grid->Cells[12][grid->Row].c_str())].
   B[atoi(grid->Cells[13][grid->Row].c_str())].
   C[atoi(grid->Cells[14][grid->Row].c_str())]=Edit1->Text;
Все норамально работает, но хочу попробовать сохранять эти значения и видимо все остальное, чтобы при создании формы все это восстанавливать. Прбовал с ini, но столкнулся с рядом вопросов. Одно значение сохраняет и я его успешно активирую при запуске. Но если их много - как сохранить, а потом активировать? И хотел сделать, что если Edit1->Text="" (то есть нет текста)- удалялась из ini структура, которая соответствует этому значению. Может вообще такое лучше делать как то по другому?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.10.2015, 15:19
Ответы с готовыми решениями:

Сохранение Image после перезапуска программы
Всем привет. Возник вопрос. Можно ли сохранить выбранную картинку в Image, чтобы после перезапуска...

Сохранение значения переменной после перезапуска программы
Здравствуйте. Допустим у меня есть переменна A и поле ввода на форме. По умолчанию переменная A...

Сохранение значения TextBox после перезапуска приложения
Здрасти. Мне нужно сохранять значения textbox после перезапуска софта. Смотрите, допустим у меня...

Сохранение элементов после перезапуска приложения
Как сделать, чтобы по нажатию кнопки в приложении создавалась новая кнопка, и после перезапуска она...

14
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
25.10.2015, 16:55 2
Sergey_03, покажи объявление структуры скажи хоть пару слов о ее назначении.

Что касается ini, сохранение множества значений не должно представлять сложностей, ведь есть секции, есть имена ключей, можно хранить данные структурированно. Что именно не получается?
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
25.10.2015, 19:03  [ТС] 3
Структура объявляется в дефайнах и используется для хранения данных из экселя. Члены не все используются. Я использую один из них.
Получается сохранить в ini и потом присвоить одно значение эдита.
Делаю так - объявляю глобально
C++
1
int AA,BB,CC; String CommentEd;
По кнопке сохраняю в ini
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if(CupperLC)
            {
                pr.p[atoi(PanelSellsOut.c_str())-1].
                d[atoi(LoopSellsOut.c_str())-1].
                ErrorLoop[atoi(AddrSellsOut.c_str())-1]=Edit5->Text;
                StringGrid7->Cells[14][RowAct]= pr.p[atoi(PanelSellsOut.c_str())-1].
                d[atoi(LoopSellsOut.c_str())-1].
                ErrorLoop[atoi(AddrSellsOut.c_str())-1];
                AA=atoi(PanelSellsOut.c_str())-1;
                BB=atoi(LoopSellsOut.c_str())-1;
                CC=atoi(AddrSellsOut.c_str())-1;
                CommentEd=Edit5->Text;
                Ini->WriteInteger("CommentEd", "AA", AA);
                Ini->WriteInteger("CommentEd", "BB", BB);
                Ini->WriteInteger("CommentEd", "CC", CC);
                Ini->WriteString("CommentEd","pr.p[AA].d[BB].ErrorLoop[CC]",CommentEd);
            }
В ini создается такая штука -
[CommentEd]
AA=0
BB=0
CC=99
pr.p[AA].d[BB].ErrorLoop[CC]=1110REditor - это моя запись в пятом эдите

потом при создании формы
C++
1
2
3
4
5
AA=Ini->ReadInteger("CommentEd", "AA", AA);
    BB=Ini->ReadInteger("CommentEd", "BB", BB);
    CC=Ini->ReadInteger("CommentEd", "CC", CC);
    pr.p[AA].d[BB].ErrorLoop[CC] =
    Ini->ReadString("CommentEd","pr.p[AA].d[BB].ErrorLoop[CC]","Def");
Не получается -
Цитата Сообщение от Sergey_03 Посмотреть сообщение
Но если их много - как сохранить, а потом активировать? И хотел сделать, что если Edit5->Text="" (то есть нет текста)- удалялась из ini структура, которая соответствует этому значению.
Может есть, где про это написано конкретно. Или может вообще можно по другому.
0
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
25.10.2015, 21:05 4
Для полной ясности, вот это вот что за чудовищная по своей элегантности запись?
C++
1
2
3
                pr.p[atoi(PanelSellsOut.c_str())-1].
                d[atoi(LoopSellsOut.c_str())-1].
                ErrorLoop[atoi(AddrSellsOut.c_str())-1]=Edit5->Text;
pr - это, надо полагать, некая хитрая структура, так? Так вот, если оптимизировать ее реализацию, сделать именованной и создать, к примеру, массив таких структур, то можно будет довольно легко все это дело писать на хранение.
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
25.10.2015, 21:21  [ТС] 5
Цитата Сообщение от BRcr Посмотреть сообщение
pr - это, надо полагать, некая хитрая структура
массив и есть (грубо говоря - массив файлов .xls проекта(файлы панелей, которые входят в проект)),p.p.panel_ID только не в этом сейчас проблема.
проблема с незнанием работы с ini
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32836 / 21173 / 8148
Регистрация: 22.10.2011
Сообщений: 36,432
Записей в блоге: 8
25.10.2015, 21:23 6
Цитата Сообщение от Sergey_03 Посмотреть сообщение
если Edit1->Text="" (то есть нет текста)- удалялась из ini структура, которая соответствует этому значению
C++
1
2
3
4
    if(CommentEd->Text.Trim().IsEmpty()) // пусто?
        Ini->DeleteKey("CommentEd", "pr.p[AA].d[BB].ErrorLoop[CC]"); // удаляем ключ
    else
        Ini->WriteString("CommentEd","pr.p[AA].d[BB].ErrorLoop[CC]",CommentEd); // иначе пишем значение CommentEd
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
26.10.2015, 11:19  [ТС] 7
Цитата Сообщение от volvo Посмотреть сообщение
DeleteKey
этот вопрос решен. Множественное сохранение значений в течении сеанса работы программы и дальнейшая работа с ini не получается. А вообще использовать для этих целей ini - нормально?

Добавлено через 13 часов 39 минут
Сейчас создаю секции
C++
1
Ini->WriteInteger("CommentEd"+PanelSellsOut+LoopSellsOut+AddrSellsOut, "AA", AA);
и т.д
потом в циклах (вложенные) про активации обхожу все члены структуры
C++
1
2
3
4
5
6
7
8
for(int P=0;P<  17;  P++)
        {
            for(int L=0;L<  2;  L++)
                {
                    for(int A=0;A<  641;  A++)
                        {
                            if(Ini->SectionExists("CommentEd"+IntToStr(P+1)+IntToStr(L+1)+IntToStr(A+1)))
                                {......
Но это долговато..
Можно как то в строке - if(Ini->SectionExists(.....<-указывать не полное название секции, а часть его - CommentEd например?

потому что этих записей может быть максимум штук 40, с запасом 100.
0
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
26.10.2015, 11:27 8
Цитата Сообщение от Sergey_03 Посмотреть сообщение
Множественное сохранение значений в течении сеанса работы программы и дальнейшая работа с ini не получается. А вообще использовать для этих целей ini - нормально?
Нормально, почему нет.
Вот кусок для примера работы с ini, примерно похожая на твою ситуация:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    std::auto_ptr < TMemIniFile > ini_config;
    typedef std::map < String, t_sequence > t_map_sequences;
 
    t_map_sequences map_seqs;
 
    void save_sequence( String sq_name )
    {
        t_map_sequences::iterator it_sq( map_seqs.find( sq_name ) );
        if ( it_sq == map_seqs.end( ) )
        {
            ShowMessage( "Oooops! No such sequence name." ); // well... who knows?  )))
            return;
        }
        t_sequence sq( it_sq->second );
 
        ini_config->WriteInteger( sq_name, "sl_files_delimiter", int( sq.sl_files->Delimiter ) );
        ini_config->WriteString( sq_name, "sl_files", sq.sl_files->DelimitedText );
        ini_config->WriteString( sq_name, "s_current_file", sq.s_current_file );
        ini_config->WriteInteger( sq_name, "i_current_pos", sq.i_current_pos );
        ini_config->WriteInteger( sq_name, "i_starting_pos", sq.i_starting_pos );
 
        ini_config->UpdateFile( );
    }
 
    void load_all( void )
    {
        std::auto_ptr < TStringList > sl_sections( new TStringList( ) );
 
        ini_config->ReadSections( sl_sections.get( ) );
        if ( sl_sections->IndexOf( "sw_options" ) >= 0 )
        {
            sl_sections->Delete( sl_sections->IndexOf( "sw_options" ) );
        }
 
        for ( int i( 0 ), i_limit( sl_sections->Count ); i < i_limit; ++i )
        {
            String sq_name( sl_sections->Strings[ i ] );
            t_sequence & sq( map_seqs[ sq_name ] );
 
            sq.sl_files->Delimiter = wchar_t( ini_config->ReadInteger( sq_name, "sl_files_delimiter", ',' ) );
            sq.sl_files->DelimitedText = ini_config->ReadString( sq_name, "sl_files", "" );
            sq.s_current_file = ini_config->ReadString( sq_name, "s_current_file", "" );
            sq.i_current_pos = ini_config->ReadInteger( sq_name, "i_current_pos", 0 );
            sq.i_starting_pos = ini_config->ReadInteger( sq_name, "i_starting_pos", 0 );
        }
 
    }
 
    void save_all( void )
    {
        ini_config->WriteString( "sw_options", "sw_version", "0.01" );
 
        for ( t_map_sequences::iterator it( map_seqs.begin( ) ), end( map_seqs.end( ) ); it != end; ++it )
        {
            save_sequence( it->first );
        }
    }
Здесь t_sequence - некая структура с информацией. Произвольное количество таких структур хранится в контейнере std::map и соответственно они поименованы посредством ключей контейнера. При сохранении в ini(тут это TMemIniFile) в качестве названий секций выступают имена структур. При загрузке имена секций считываются и на их основе конструируются новые именованные структуры. Все параметры отдельно взятой структуры хранятся в секции с соответствующим ей названием.
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
26.10.2015, 11:30  [ТС] 9
Цитата Сообщение от BRcr Посмотреть сообщение
Нормально, почему нет.
Спасибо, буду разбираться
Или обойти ini по строкам в цикле и все секции со словом CommentEd активировать?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32836 / 21173 / 8148
Регистрация: 22.10.2011
Сообщений: 36,432
Записей в блоге: 8
26.10.2015, 11:33 10
Цитата Сообщение от Sergey_03 Посмотреть сообщение
Можно как то в строке - if(Ini->SectionExists(.....<-указывать не полное название секции, а часть его
Нет, нельзя, название секции должно быть полным.

Просто для информации, можно получить одним методом ReadSections список всех секций файла, возможно пригодится, потом пробежать по полученному StringList-у и проверить на наличие определенной секции всяко проще (и уж точно быстрее), чем каждый раз вызывать SectionExists, которая все равно делает то же самое, точно так же получает через ReadSections список всех секций при каждом вызове, да еще и обернута тонной другого кода.
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
26.10.2015, 12:56  [ТС] 11
Цитата Сообщение от volvo Посмотреть сообщение
Просто для информации
чего то не догнать. А как это применить к моей ситуации, маленький примерчик можно?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32836 / 21173 / 8148
Регистрация: 22.10.2011
Сообщений: 36,432
Записей в блоге: 8
26.10.2015, 14:42 12
Цитата Сообщение от Sergey_03 Посмотреть сообщение
как это применить к моей ситуации
Больше кода покажи, что именно у тебя делается после этой самой проверки, существует ли секция - я покажу, как применить то, что предложил.
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
26.10.2015, 14:55  [ТС] 13
Цитата Сообщение от volvo Посмотреть сообщение
Больше кода покажи, что именно у тебя делается после этой самой
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for(int P=0;P<  MAX_PANELS;  P++)
    {  p.p.panel_ID=P;
    for(int L=0;L<  MAX_LOOP;  L++)
    {
    for(int A=0;A<  MAX_DEVICE;  A++)
    {
    if(Ini->SectionExists("PanLoopAdr"+IntToStr(P+1)+IntToStr(L+1)+IntToStr(A+1)))
        {
            AA=Ini->ReadInteger("PanLoopAdr"+IntToStr(P+1)+IntToStr(L+1)+IntToStr(A+1), "AA", AA);
            BB=Ini->ReadInteger("PanLoopAdr"+IntToStr(P+1)+IntToStr(L+1)+IntToStr(A+1), "BB", BB);
            CC=Ini->ReadInteger("PanLoopAdr"+IntToStr(P+1)+IntToStr(L+1)+IntToStr(A+1), "CC", CC);
            pr.p[AA].d[BB].ErrorLoop[CC] =
            Ini->ReadString("PanLoopAdr"+IntToStr(P+1)+IntToStr(L+1)+IntToStr(A+1),
            "pr.p[AA].d[BB].ErrorLoop[CC]","Def");
        }
    }
    }
    }
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32836 / 21173 / 8148
Регистрация: 22.10.2011
Сообщений: 36,432
Записей в блоге: 8
26.10.2015, 15:01 14
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    TStringList *sections = new TStringList;
    Ini->ReadSections(sections);
 
    for (int P = 0; P < MAX_PANELS; P++)
    {
        p.p.panel_ID = P;
        for (int L = 0; L < MAX_LOOP; L++)
        {
            for (int A = 0; A < MAX_DEVICE; A++)
            {
                // строка составляется 1 раз, а не 5 - экономия времени
                String name = String().sprintf(L"PanLoopAdr%d%d%d", P + 1, L + 1, A + 1);
                // IndexOf будет выполняться быстрее, чем SectionExists
                if (sections->IndexOf(name) > -1)
                {
                    AA = Ini->ReadInteger(name, "AA", AA);
                    BB = Ini->ReadInteger(name, "BB", BB);
                    CC = Ini->ReadInteger(name, "CC", CC);
                    pr.p[AA].d[BB].ErrorLoop[CC] = Ini->ReadString(name, "pr.p[AA].d[BB].ErrorLoop[CC]", "Def");
                }
            }
        }
    }
    delete sections;
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
26.10.2015, 15:23  [ТС] 15
Спасибо огромное! Все быстро работает. У меня там семь структур таким образом нужно обойти, так что это очень важно.
0
26.10.2015, 15:23
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.10.2015, 15:23
Помогаю со студенческими работами здесь

Сохранение информации после перезапуска программы
VB в Microsoft Visual Studio 2008 (Windows Forms Application). Нужно, чтобы переменная string,...

Сохранение информации после перезапуска приложения
Всем здравствуйте, возник такой вопрос нужна переменная в которой будет храниться какая либо...

Изменение цвета Checkbox и сохранение после перезапуска
День добрый, как реализовать чтобы выделенные чекбоксы после нажатия на &quot;Красный&quot; или &quot;Зеленый&quot;...

Сохранение данных в Listbox после перезапуска программы
Можно ли это сделать, не создавая дополнительных текстовых файлов? Если можно только используя...

Сохранение элементов ListBox после перезапуска приложения
Как можно сохранить данные в ListBox после выхода из проги? В Aplication Setting, создавал параметр...

Сохранение ширины столбцов DGV после перезапуска программы
Всем привет! Есть программка, как сделать так, что после того как юзер изменил ширину столбцов в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru