Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/653: Рейтинг темы: голосов - 653, средняя оценка - 4.89
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1

INI - Загрузка и сохранение настроек

10.01.2013, 05:40. Показов 126380. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Сохраняем настройки в INI-файлах

Большинство программистов сталкиваются с проблемой сохранения настроек своей программы, но сегодня мы решим эту проблему. Мы научимся работать с ini файлами. Еще одним способом сохранять настройки является реестр, но его лучше не изменять, да и работать с ним немного сложнее.

Итак, ini-файл имеет простую и понятную структуру :
[Секция1]
Идентификатор1 = Значение1
Идентификатор2 = Значение2
[Секция2]
Идентификатор1 = Значение1
Для использования ini-файлов, в C++Builder предусмотрен модуль IniFiles , его мы и подключаем:
C++
1
#include "IniFiles.hpp"
Далее, нужно создать обьект класса TIniFile, назовем его Ini.

После
C++
1
TForm1 *Form1;
пишем:
C++
1
TIniFile *Ini = new TIniFile("c:/options.ini");
значения сохраняет на диске С: в файл options.ini .

После этого, на форму кинем две кнопки (TButton) и два Эдита (TEdit). Мы будем сохранять текст Эдитов в ini-файл, а потом загружать его.
Пишем обработчик события нажатия кнопки Button1. Она будет сохранять текст Эдитов в наш options.ini
C++
1
2
3
4
5
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Ini->WriteString("Edits","Edit1",Edit1->Text);
    Ini->WriteString("Edits","Edit2",Edit2->Text);
}
Так, как мы работаем с текстом, мы использовали метод класса WriteString,
если нам нужно было бы работать с числами, мы бы написали WriteInteger .

Где параметры для этой функции:
"Edits" - имя секции;
"Edit1" - указатель на объект;
"Edit1->Text" - строка, которую мы сохраняем (текст эдита).

Далее, рассмотрим пример загрузки параметров с ini , пишем обработчик события для второй кнопки:
C++
1
2
3
4
5
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    Edit1->Text = Ini->ReadString("Edits","Edit1","Def");
    Edit2->Text = Ini->ReadString("Edits","Edit2","Def");
}
Здесь используем функцию чтения :ReadString , где:

"Edits" - секция из которая нам надо ;
"Edit1" - объект для которого загружаем строку;
"Def" - эта строка заполняет Эдит, если значение ini не найдено;

Этот маленький пример показывает как можно лекго загружать и сохранять параметры программы в INI-файлы.

Методы и свойства реализуемые TIniFile
Использовать или установить это ... Чтобы сделать это ... Наследование
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
Create          Сконструировать экземпляр TIniFile.             TObject
DeleteKey           Удалить идентификатор INI-файла и его значение.        Нет
EraseSection        Убрать из INI-файла целый раздел.               Нет
FileName            Получить инкапсулированное имя INI-файла.          Нет
ReadBool            Извлечь из INI-файла логическое значение.           Нет
Readinteger         Извлечь из INI-файла целое значение.         Нет
ReadSection         Извлечь из раздела INI-файла имена идентификаторов.    Нет
ReadSections        Извлечь из INI-файла список имен разделов.      Нет
ReadSectionValues       Извлечь из INI-файла все содержимое раздела.      Нет
ReadString          Извлечь из INI-файла строковое значение.         Нет
WriteBool           Записать в INI-файл логическое значение.         Нет
Writeinteger        Записать в INI-файл целое значение                Нет
WriteString         Записать в INI-файл строковое значение            Нет
Важно
Методы ТIniFile будут пытаться найти INI-файл в каталоге Windows. Если вы хотите читать или писать INI-файл, расположенный не в каталоге Windows, следует явно добавить путь к имени INI-файла при его открытии в Create.

Автозагрузка конфигурации

Создаем 2 кнопки, раздела меню, т.д которые будут отвечать за запись файла, чтение файла конфигурации.

Код примерно такой (для 2 CheckBox'ов):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// SAVE
void __fastcall TForm1::Button1Click(TObject *Sender){
  AnsiString FileName = ExtractFilePath( Application->ExeName ) + "config.dat";
  ofstream fout( FileName.c_str() );
 
  if( fout ){
    fout << CheckBox1->Checked << endl;
    fout << CheckBox2->Checked << endl;
    fout.close();
  }
}
// LOAD
void __fastcall TForm1::Button2Click(TObject *Sender){
  AnsiString FileName = ExtractFilePath( Application->ExeName ) + "config.dat";
  ifstream fin( FileName.c_str() );
  bool check = false;
 
  if( fin ){
    CheckBox1->Checked = ( fin >> check, check );
    CheckBox2->Checked = ( fin >> check, check );
    fin.close();
  }
}
Теперь для записи конфигурации нужно вызвать функцию
C++
1
Button1Click(Sender);
для чтения
C++
1
Button2Click( Sender );
Например чтобы при закрытии приложения конфигурация автомитически сохранялась, надо написать обработчик события OnClose для формы.
C++
1
2
3
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action){
  Button1Click( Sender );
}
Чтобы автоматически загружалась - обработчик OnCreate
C++
1
2
3
void __fastcall TForm1::FormCreate(TObject *Sender){
  Button2Click( Sender );
}
для работы ofstream и ifstream необходимо включить заголовочный файл
C++
1
#include <fstream.h>
Обработка события изменения CheckBox - OnClick
C++
1
2
3
4
5
6
7
void __fastcall TForm1::CheckBox1Click(TObject *Sender){
  if( CheckBox1->Checked ){
//...
  } else{
//...
  }
}
Сделать структуру, например, в .h-файле, такого вида:
C++
1
2
3
4
struct TParameters
{
  bool IfFormatCOnUpload;  // всякие параметры, например, - булевские переменные
};
Создать объект этой структуры.

Например, в FormDestroy все писать в реестр, в Ini-файл или в какой-нибудь бинарный, а при создании окна все загружать и проставлять индикаторы.

При изменении параметры структуры тоже изменять или же смотреть все в самом конце.

Чтобы узнать последнюю просматривавшуюся, надо в OnChange у комбобокса написать:
C++
1
LastIndex = ComboBox1->ItemIndex;
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
TIniFile * Ini; // объект .ini-файла
 
void __fastcall TForm1::WriteParams()  // запись всех значений в .ini-файл
{
   Ini->WriteInteger ( "Form1", "Form1Width",         Width               );  // ширина
   Ini->WriteInteger ( "Form1", "Form1Height",        Height              );  // высота
   Ini->WriteInteger ( "Form1", "Form1Top",           Top                 );  // вершина
   Ini->WriteInteger ( "Form1", "Form1Left",          Left                );  // лево
   Ini->WriteString  ( "Form1", "Form1Caption",       Caption             );  // заголовок
   Ini->WriteInteger ( "Form1", "ComboBox1ItemIndex", ComboBox1->ItemIndex);  // индекс
   Ini->WriteBool    ( "Form1", "CheckBox1Checked",   CheckBox1->Checked  );  // состояние 1
   Ini->WriteBool    ( "Form1", "CheckBox2Checked",   CheckBox2->Checked  );  // состояние 2
   Ini->WriteBool    ( "Form1", "InitMax",    WindowState == wsMaximized  );  // вид формы
   Ini->WriteString  ( "Memos", "Form1Memo1",         Memo1->Text         );  // содержимое
   Ini->UpdateFile();  // это обязательно, чтобы заново переписался файл
}
 
void __fastcall TForm1::ReadParams()
{
   Width                = Ini->ReadInteger( "Form1", "Form1Width",         800     );  // ширина
   Height               = Ini->ReadInteger( "Form1", "Form1Height",        600     );  // высота
   Top                  = Ini->ReadInteger( "Form1", "Form1Top",           100     );  // вершина
   Left                 = Ini->ReadInteger( "Form1", "Form1Left",          200     );  // лево
   Caption              = Ini->ReadString ( "Form1", "Form1Caption",       "MyProg");  // заголовок
   ComboBox1->ItemIndex = Ini->ReadInteger( "Form1", "ComboBox1ItemIndex", 0       );  // индекс
   CheckBox1->Checked   = Ini->ReadBool   ( "Form1", "CheckBox1Checked",   true    );  // состояние 1
   CheckBox2->Checked   = Ini->ReadBool   ( "Form1", "CheckBox2Checked",   true    );  // состояние 2
   WindowState          = Ini->ReadBool   ( "Form1", "InitMax", false) ? wsMaximized : wsNormal;
   Memo1->Text          = Ini->ReadString ( "Memos", "Form1Memo1",         ""      );  // содержимое
}
 
void __fastcall TForm1::FormCreate(TObject * Sender)  // создание формы
{
  Ini = new TIniFile(ExtractFilePath(Application->ExeName) + "mytestini.ini");  // создаем объект
  ReadParams();   // считываем все в поля из файла
}
 
void __fastcall TForm1::FormDestroy(TObject * Sender)
{
  WriteParams();  // записываем все в последний раз
  delete Ini;     // удаляем объект
}
 
void __fastcall TForm1::BtnSaveClick(TObject * Sender)
{  WriteParams();  }  // сохранение при нажатии кнопки
 
void __fastcall TForm1::BtnLoadClick(TObject * Sender)
{  ReadParams();  }   // загрузка при нажатии кнопки
Чтобы не приучатся писать лишнего кода достаточно объявить функции
C++
1
2
void __fastcall ReadParams( TObject *Sender );
void __fastcall WriteParams( TObject *Sender );
в части класса формы
C++
1
(TForm1) __published:
и потом в инсперторе объектов для BtnLoad обработчиком события выбрать ReadParams.

Для Save аналогично.

Можно, но очень даже возможно, что при нажатии этих кнопок кроме как загружать данные из файла, надо еще что-то делать, поэтому, и чтобы не запутаться, это выделено в разные места.

Запись данных из файла INI в Memo
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  TIniFile *ini = new TIniFile(ExtractFileDir(Application->ExeName) + "\\MyFile.ini");
  TStringList* Sections = new TStringList;
  TStringList* Values = new TStringList;
  if (ini) {
    ini->ReadSections(Sections);
    for (int i=0; i<Sections->Count; i++) {
      Memo1->Lines->Add("--------------\r\n" + Sections->Strings[i] + "\r\n--------------");
      ini->ReadSectionValues(Sections->Strings[i], Values);
      for (int j=0; j<Values->Count; j++) Memo1->Lines->Add(Values->Strings[j]);
    }
    delete ini;
  }
 
  delete Values;
  delete Sections;
}
Как создать Ini-файл в директории программы

По умолчанию ini-файл создается в Windows-директории (например: TIniFile.Create('FOO.INI' )), что приводит к "захламлению" оной. Более (эко-)логично (за исключением случаев, когда программа делается для CD-ROM) если ini-файл создается в той же директории что и главная программа. Это достигается с помощью одной строки:
C++
1
IniFile := TIniFile.Create(ChangeFileExt(ParamStr(0),'.INI'));
Как сохранить FontDlg->Style в 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
TFont *CaptionFont = new TFont();
//Параметры стиля запоминается как bool значения
//Установку параметра шрифта проверяем через Contains
//Запись параметров шрифта
ini->WriteString(Key, "CFN", CaptionFont->Name);//
ini->WriteInteger(Key, "CFS", CaptionFont->Size);//
ini->WriteInteger(Key, "CFC", (int)CaptionFont->Color);//
ini->WriteInteger(Key, "CFE", (int)CaptionFont->Charset);//
ini->WriteBool(Key, "CFB", CaptionFont->Style.Contains(fsBold));
ini->WriteBool(Key, "CFI", CaptionFont->Style.Contains(fsItalic));//
ini->WriteBool(Key, "CFU", CaptionFont->Style.Contains(fsUnderline));//
ini->WriteBool(Key, "CFO", CaptionFont->Style.Contains(fsStrikeOut));//
 
//Чтение параметров шрифта
//ПРи чтении внвчале сбрасываем все параметры шрифта, а потом добавляем
//требуемый в множество в соответствии с прочитанным bool параметром
//Может можно и удалять эелементы из множества,
//но что-то в Help'е описывают только добавление.
CaptionFont->Style.Clear();//Сбросить параметры шрифта
CaptionFont->Name = ini->ReadString(Key, "CFN", CaptionFont->Name);//
CaptionFont->Size = ini->ReadInteger(Key, "CFS", 12);//
CaptionFont->Color = (TColor) ini->ReadInteger(Key, "CFC", clBlack);//
CaptionFont->Charset = (unsigned char)ini->ReadInteger(Key, "CFE", 204);//
if (ini->ReadBool(Key, "CFB", false))//
CaptionFont->Style = CaptionFont->Style << fsBold;//
if (ini->ReadBool(Key, "CFI", false))//
CaptionFont->Style = CaptionFont->Style << fsItalic;//
if (ini->ReadBool(Key, "CFU", false))//
CaptionFont->Style = CaptionFont->Style << fsUnderline;//
if (ini->ReadBool(Key, "CFO", false))//
CaptionFont->Style = CaptionFont->Style << fsStrikeOut;//
 
//P.S.: по идее должно работать и просто CaptionFont->Style << fsItalic;
//вместо CaptionFont->Style = CaptionFont->Style << fsItalic;
Как записать и считать переменную из ini
C++
1
2
3
4
5
6
7
8
9
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  AnsiString info = "ABCDEFGH";
  TIniFile *ini = new TIniFile("C:\\Program Files\\Borland\\CBuilder6\\Projects\\pr_ini\\file.ini");
  ini->WriteString( "section", "name", info);
  AnsiString info2 = ini->ReadString( "section", "name", "No Value");
  ShowMessage(info2); // получаем ABCDEFGH
  delete ini; ini = NULL;
}
Как считать секцию из файла ini
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <Inifiles.hpp>
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  TIniFile* pif = new TIniFile("WIN.INI");
  pif->ReadSections(ListBox1->Items);
  pif->ReadSection("Ports",ListBox2->Items);
  pif->ReadSectionValues("Ports",ListBox3->Items);
  delete pif;
}
 
MyIni->WriteInteger("NumOfItems","ItemsCount",ListBox1->Items->Count);
for (int j=0,cnt=ListBox1->Items->Count;j<cnt;j++) {
  MyIni->WriteString("Listbox","Item"+IntToStr(j),ListBox1->Items->Strings[j]);
}
 
void __fastcall TForm1::FormCreate(TObject *Sender)
{
 int j,cnt;
 cnt=StrToInt(MyIni->ReadString("NumOfItems","ItemsCount","0"));
 for (j=0;j<cnt;j++)
 ListBox1->Items->Add(MyIni->ReadString("ListBox","Item"+IntToStr(j),"N/A"));
}
Количество секций и ключей
C++
1
2
3
4
5
6
7
8
9
TIniFile *iniFile = TIniFile(iniFileName);
TStringList *iniKeys = new TStringList;
TStringList *iniSections = new TStringList;
 
iniFile->ReadSections(iniSections);
ShowMessage(IntToStr(iniSections->Count)); // Количество секций
 
iniFile->ReadSection("General", iniKeys);
ShowMessage(IntToStr(iniKeys->Count)); // Количество ключей
Количество ключей в секции
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
TIniFile *iniFile = TIniFile(iniFileName);
TStringList *iniKeys = new TStringList;
TStringList *iniSections = new TStringList;
iniFile->ReadSections(iniSections);
ShowMessage(IntToStr(iniSections->Count)); // Количество секций
iniFile->ReadSection(SectionName, iniKeys);
ShowMessage(IntToStr(iniKeys->Count)); // Количество ключей
  unsigned long int CIni::ulSectionSize(const char *pszSection) {
  unsigned long int ulRes = 0;
  const unsigned int uiBuffLen = LINES_PER_SECTION * LINE_LEN;
  char szBuff[uiBuffLen];
  memset(szBuff, 0, uiBuffLen);
 
  GetPrivateProfileSection(pszSection, szBuff, uiBuffLen, m_sFilePath.c_str());
  //"Key1=xxx1"0"Key2=xxx2"0"Key2=xxx2"
  //если секция пустая
  if (szBuff[0] == '\0') {
    return 0;
  } 
  //секция не пустая
  for (int i = 0; i < uiBuffLen; i ++) {
    if (szBuff[i] == '\0') {
      ulRes ++;
       //конец данных '\0\0'
       if (szBuff[i + 1] == '\0') {
         break;
      }                
    }
  }    
  return ulRes;
}
Дополнительно

Файл конфигурации
Working with INI Configuration Files Cross-Platform (Win32/Un*x, MBCS/Unicode)

IniFilesTMemIniFile (C++)
Using TIniFile and TMemIniFile
Using TRegistryIniFile
THashedStringList

iniFile
DLL как контейнер языковых файлов
Клавиша руки обжигает!
Скрыть строку с memo
INI Файл и Стиль Шрифта - как сохранить в INI стиль шрифта.
Клавиша руки обжигает!
Максимальная длина строки TMemo/TRichEdit/TIniFile

StringList - Связь с INI-файлами
Парсер файлов ini
Работа с файлами INI
SimpleIni
How to use an ini file in C++Builder

Исходники
Запись и считывание очень длинной строки
Проект с примером реализации: Калькулятор Buidler

Не по теме:

Всех источников не помню. По поводу авторских прав, ошибок, дополнений и улучшений - пишите в личку.

25
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.01.2013, 05:40
Ответы с готовыми решениями:

Сохранение настроек в INI
Здравствуйте ! Почитал эту тему https://www.cyberforum.ru/cpp-builder/thread757450.html . Все хорошо , но не понял, как мне сделать...

Сохранение настроек в Ini из ComboBox.
Разобрался с ini файлом, вот только возник вопрос, как сохранить настройки из COmboBox void __fastcall TForm4::FormCreate(TObject...

Сохранение настроек программы в *ini файл.
Как сохранить параметры программы в файл *ini ?

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.01.2013, 05:40
Помогаю со студенческими работами здесь

Загрузка настроек из ini файла, что-то странное...
Всем привет! Написал я тут одну прогу. Она сохраняет свои настройки в Settings.ini а при запуске загружает их. Если просто запустить...

Загрузка настроек из INI файла для CheckBox
Сохранение и загрузка настроек из INI файла. Настройки все удачно сохраняются, а вот загружаться для CheckBox'ов никак не хотят В чем...

Сохранение TrackBar->Position в ini, ошибка (unable to write to options.ini)
TIniFile *Ini = new TIniFile(&quot;options.ini&quot;); void __fastcall TForm2::Button5Click(TObject *Sender) { ...

Сохранение положения компонента на форме (Сохранение параметра в Ini-файл)
Не знаю верно ли назвал тему. Доброго вечера тебе, всяк сюда входящий. Подскажите пожалуйста с вопросом: Имеется Form1, на нем...

INI - Загрузка и сохранение настроек
Добрый день. Подскажите пожалуйста. Существует ли какой либо класс в C++ в Visual Studio для &quot;INI - Загрузка и сохранение...


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

Или воспользуйтесь поиском по форуму:
1
Закрытая тема Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru