C++ read and write ini configuration file implementation details

  • 2020-10-31 21:54:40
  • OfStack

Under Windows VC

Read ini files

For example: in the D:\ test.ini file

[

[Font]
name = tahoma
size= 12pt
color = RGB(255,0,0)

]

The = sign above can be blank or blank

Use GetPrivateProfileInt () and GetPrivateProfileString ()


[section]
key=string
   .
   .

 To obtain integer
UINT GetPrivateProfileInt(
 LPCTSTR lpAppName, // section name
 LPCTSTR lpKeyName, // key name
 INT nDefault,    // return value if key name not found
 LPCTSTR lpFileName // initialization file name
);

 Note: lpAppName and lpKeyName Case - insensitive when obtained integer <0, Then the return 0 . lpFileName  Must be an absolute path, because the relative path is a C:\windows\

DWORD GetPrivateProfileString(
 LPCTSTR lpAppName,    // section name
 LPCTSTR lpKeyName,    // key name
 LPCTSTR lpDefault,    // default string
 LPTSTR lpReturnedString, // destination buffer
 DWORD nSize,       // size of destination buffer
 LPCTSTR lpFileName    // initialization file name
);

 Note: lpAppName and lpKeyName Case insensitive, if lpAppName for NULL . lpReturnedString I'm going to load this in the buffer ini A list of all sections of the file, if lpKeyName=NULL , in the lpReturnedString The buffer contains a list of all items in the specified section. lpFileName  Must be an absolute path, because the relative path is a C:\windows\ . 
 Return value: copy to lpReturnedString The number of characters in the buffer, excluding those NULL Abort character. Such as lpReturnedString The buffer is not large enough to hold all the information nSize-1 (if lpAppName or lpKeyName for NULL , the return nSize-2 ) 

 To obtain a 1 All of the fields keys and values
DWORD GetPrivateProfileSection(
 LPCTSTR lpAppName,    // section name
 LPTSTR lpReturnedString, // return buffer
 DWORD nSize,       // size of return buffer
 LPCTSTR lpFileName    // initialization file name
);

retrieves the names of all sections in an initialization file.
DWORD GetPrivateProfileSectionNames(
 LPTSTR lpszReturnBuffer, // return buffer
 DWORD nSize,       // size of return buffer
 LPCTSTR lpFileName    // initialization file name
);
 Which is essentially equal to, GetPrivateProfileString(NULL,NULL,lpszReturnedBuffer,nSize,lpFileName)

Example:


/* test.ini "=" You can add space on both sides of the sign, or not 
  [Font]
  name= Song typeface 
  size= 12pt
  color = RGB(255,0,0)
  [Layout]
  [Body]
  */

  CString strCfgPath = _T("D:\\test.ini"); // Note: '\\'
  LPCTSTR lpszSection = _T("Font");
  int n = GetPrivateProfileInt(_T("FONT"), _T("size"), 9, strCfgPath);//n=12
  CString str;
  GetPrivateProfileString(lpszSection, _T("size"), _T("9pt"), str.GetBuffer(MAX_PATH), MAX_PATH, strCfgPath);
  str.ReleaseBuffer();//str="12pt"

  TCHAR buf[200] = { 0 };
  int nSize = sizeof(buf) / sizeof(buf[0]);
  GetPrivateProfileString(lpszSection, NULL, _T(""), buf, nSize, strCfgPath);
  //buf: "name\0size\0color\0\0"

  memset(buf, 0, sizeof(buf));
  GetPrivateProfileString(NULL, _T("size"), _T(""), buf, nSize, strCfgPath);// no Section . _T("size") It doesn't make any sense, so I can write it NULL
  // Can be  GetPrivateProfileString(NULL, NULL, _T(""), buf, nSize, strCfgPath);
  //buf: "Font\0Layout\0Body\0\0"

  memset(buf, 0, sizeof(buf));
  GetPrivateProfileSection(lpszSection, buf, nSize, strCfgPath);
  //buf: "name= Song typeface \0size=12pt\0color=RGB(255,0,0)\0\0"   At this time" = "There will be no Spaces on either side 

  memset(buf, 0, sizeof(buf));
  GetPrivateProfileSectionNames(buf, nSize, strCfgPath);// Is equal to the GetPrivateProfileString(NULL, NULL, _T(""), buf, nSize, strCfgPath);
  //buf: "Font\0Layout\0Body\0\0"

Write ini files

WritePrivateProfileString function, no integer, can be converted to string to write.


BOOL WritePrivateProfileString(
 LPCTSTR lpAppName, // section name
 LPCTSTR lpKeyName, // key name
 LPCTSTR lpString,  // string to add
 LPCTSTR lpFileName // initialization file
);

The WritePrivateProfileSection function replaces the keys and values for the specified section in an initialization file. 

BOOL WritePrivateProfileSection(
 LPCTSTR lpAppName, // section name
 LPCTSTR lpString,  // data
 LPCTSTR lpFileName // file name
);

WritePrivateProfileString:

Remarks

[

If the lpFileName parameter does not contain a full path and file name for the file, WritePrivateProfileString searches the Windows directory for the file. If the file does not exist, this function creates the file in the Windows directory.

If lpFileName contains a full path and file name and the file does not exist, WritePrivateProfileString creates the file. The specified directory must already exist.

]

WritePrivateProfileSection:

Remarks

[

The data in the buffer pointed to by the lpString parameter consists of one or more null-terminated strings, followed by a final null character. Each string has the following form:

key=string

The WritePrivateProfileSection function is not case-sensitive; the string pointed to by the lpAppName parameter can be a combination of uppercase and lowercase letters.

If no section name matches the string pointed to by the lpAppName parameter, WritePrivateProfileSection creates the section at the end of the specified initialization file and initializes the new section with the specified key name and value pairs.

WritePrivateProfileSection deletes the existing keys and values for the named section and inserts the key names and values in the buffer pointed to by the lpString parameter. The function does not attempt to correlate old and new key names; if the new names appear in a different order from the old names, any comments associated with preexisting keys and values in the initialization file will probably be associated with incorrect keys and values.

This operation is atomic; no operations that read from or write to the specified initialization file are allowed while the information is being written.

]

Example:


WritePrivateProfileString(_T("Layout"), _T("left"), _T("100"), strCfgPath);
  WritePrivateProfileString(_T("Layout"), _T("top"), _T("80"), strCfgPath);
  // Delete a Section, including [Layout] And everything below it Keys=Value
  WritePrivateProfileSection(_T("Layout"), NULL, strCfgPath);
  // Delete a Section, including [Layout] Under all Keys=Value, But don't delete [Layout]
  WritePrivateProfileSection(_T("Layout"), _T(""), strCfgPath);
// And: WritePrivateProfileSection(NULL, NULL, strCfgPath); Nothing, because Section for NULL

Self-encapsulating functions:

Gets all key=value for a given Section

map < CString, CString > GetKeysValues(LPCTSTR szSection, LPCTSTR szIniFilePath)

Gets all Section names for the ini file

vector < CString > GetSectionsNames(LPCTSTR szIniFilePath)


#include <vector>
#include <map>
using std::vector;
using std::map;
// To obtain ini All of the files Section The name 
vector<CString> GetSectionsNames(LPCTSTR szIniFilePath)
{
  vector<CString> vRet;
  TCHAR buf[2048] = { 0 };
  long nSize = sizeof(buf) / sizeof(buf[0]);
  ::GetPrivateProfileSectionNames(buf, nSize, szIniFilePath);
  TCHAR *p, *q;
  p = q = buf;
  while (*p)// namely  '\0' != *p
  {
    while (*q)
    {
      ++q;
    }
    CString str(p, q - p);
    vRet.push_back(str);
    p = q + 1;
    q = q + 1;
  }
  return vRet;
}
// To obtain a 1 a Section All of the  key=value
map<CString, CString> GetKeysValues(LPCTSTR szSection, LPCTSTR szIniFilePath)
{
  map<CString,CString> mapRet;
  TCHAR buf[2048] = { 0 };
  long nSize = sizeof(buf) / sizeof(buf[0]);
  GetPrivateProfileSection(szSection, buf, nSize, szIniFilePath);
  TCHAR* p = buf;
  TCHAR* q = buf;
  while (*p)
  {
    CString strKey, strValue;
    while(*q)
    {
      if (_T('=') == *q)
      {
        strKey = CString(p, q - p);
        p = q + 1;
      }
      ++q;
    }
    strValue = CString(p, q - p);
    mapRet.insert(std::make_pair(strKey, strValue));
    p = q + 1;
    q = q + 1;
  }
  return mapRet;
}

Related articles: