C/C++ INI文件操作實(shí)現(xiàn)代碼
一、INI文件用途:
1、存儲(chǔ)程序的初始化信息;
2、存儲(chǔ)需要保存的數(shù)據(jù)信息。
二、INI文件結(jié)構(gòu):
由節(jié)名、鍵名、鍵值組成。形式如下:
[節(jié)名]
鍵名 = 鍵值
備注:一個(gè)INI文件,可以用多個(gè)節(jié)。
三、讀取INI文件
1、WritePrivateProfileString
該函數(shù)用于向INI文件中寫(xiě)入一個(gè)字符串?dāng)?shù)據(jù)。
函數(shù)原型如下:
BOOL WritePrivateProfileString( LPCTSTR lpAppName, // pointer to section name LPCTSTR lpKeyName, // pointer to key name LPCTSTR lpString, // pointer to string to add LPCTSTR lpFileName // pointer to initialization filename );
參數(shù)說(shuō)明:
lpAppName:指定節(jié)名,以空終止結(jié)尾的字符串。如果INI文件中節(jié)名不存在,將創(chuàng)建一個(gè)節(jié)名。
lpKeyName:鍵名,以空終止結(jié)尾的字符串。如果INI文件中該鍵名不存在,將創(chuàng)建一個(gè)鍵名。如果該參數(shù)為NULL,包括節(jié)及節(jié)下的所有項(xiàng)目都將被刪除。
lpString:寫(xiě)到鍵值中的數(shù)據(jù),以空終止結(jié)尾的字符串。
lpFileName:INI文件的名稱,以空終止結(jié)尾的字符串。指定需要寫(xiě)入數(shù)據(jù)的INI文件,如果指定的INI文件不存在將創(chuàng)建。
返回值:
如果函數(shù)成功將字符串復(fù)制到初始化文件,返回值是非零。
如果函數(shù)失敗,刷新緩存版本的最近訪問(wèn)初始化文件,返回值是零。
2、GetPrivateProfileString
該函數(shù)用于獲取INI文件中的鍵值。
函數(shù)原型如下:
DWORD GetPrivateProfileString( LPCTSTR lpAppName, // points to section name LPCTSTR lpKeyName, // points to key name LPCTSTR lpDefault, // points to default string LPTSTR lpReturnedString, // points to destination buffer DWORD nSize, // size of destination buffer LPCTSTR lpFileName // points to initialization filename );
參數(shù)說(shuō)明:
lpAppName:指定節(jié)名,以空終止結(jié)尾的字符串。如果該參數(shù)為NULL,函數(shù)將復(fù)制所有的節(jié)名到所指定的緩沖區(qū)中。
lpKeyName:鍵名,以空終止結(jié)尾的字符串。如果該參數(shù)為NULL,函數(shù)將lpAppName節(jié)下所有的鍵名復(fù)制到lpReturnedString緩沖區(qū)。
lpDefault:默認(rèn)值,以空終止結(jié)尾的字符串。如果獲取鍵值的鍵名不存在時(shí),返回設(shè)置的默認(rèn)值。
lpReturnedString:用于接受數(shù)據(jù)的緩沖區(qū)。
nSize:以字符為單位表示lpReturnedString緩沖區(qū)的大小。
lpFileName:INI文件名稱,以空終止結(jié)尾的字符串。
返回值:
返回值是字符復(fù)制到緩沖區(qū)的數(shù)量,不包括終止null字符。
3、GetPrivateProfileInt
該函數(shù)用于從INI文件中獲取整型數(shù)據(jù)。
函數(shù)原型如下:
UINT GetPrivateProfileInt( LPCTSTR lpAppName, // address of section name LPCTSTR lpKeyName, // address of key name INT nDefault, // return value if key name is not found LPCTSTR lpFileName // address of initialization filename );
參數(shù)說(shuō)明:
lpAppName:節(jié)名。
lpKeyName:鍵名。
nDefault:默認(rèn)值。
lpFileName:INI文件名稱。
返回值:
函數(shù)返回實(shí)際讀取的整數(shù)值。
4、GetPrivateProfileSectionNames
該函數(shù)用于返回INI文件中的所有節(jié)名。
函數(shù)原型如下:
DWORD GetPrivateProfileSectionNames( LPTSTR lpszReturnBuffer, // address of return buffer DWORD nSize, // size of return buffer LPCTSTR lpFileName // address of initialization filename );
參數(shù)說(shuō)明:
lpszReturnBuffer:接受節(jié)名的數(shù)據(jù)緩沖區(qū)。
nSize:緩沖區(qū)的大小。
lpFileName:INI文件名稱。
返回值:
返回值指定數(shù)量的字符復(fù)制到指定的緩沖,不包括終止null字符。
如果緩沖區(qū)沒(méi)有大到足以包含所有相關(guān)的部分名稱指定的初始化文件,返回值等于指定的長(zhǎng)度nSize - 2。
5、GetPrivateProfileSection
該函數(shù)用于獲取指定節(jié)下的所有的鍵名和鍵值。
函數(shù)原型如下:
DWORD GetPrivateProfileSection( LPCTSTR lpAppName, // address of section name LPTSTR lpReturnedString, // address of return buffer DWORD nSize, // size of return buffer LPCTSTR lpFileName // address of initialization filename );
參數(shù)說(shuō)明:
lpAppName:節(jié)名。
lpReturnedString:用于接受數(shù)據(jù)的緩沖區(qū)。
nSize:緩沖區(qū)的大小。
lpFileName:INI文件名稱。
返回值:
返回值指定數(shù)量的字符復(fù)制到緩沖區(qū),不包括終止null字符。
如果緩沖區(qū)沒(méi)有大到足以包含所有與指定相關(guān)聯(lián)的鍵名稱和值對(duì)部分,返回值等于nSize - 2。
四、C++實(shí)現(xiàn)INI文件讀寫(xiě)完整代碼
CMyINI.h
#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <map>
using namespace std;
//INI文件結(jié)點(diǎn)存儲(chǔ)結(jié)構(gòu)
class ININode
{
public:
ININode(string root, string key, string value)
{
this->root = root;
this->key = key;
this->value = value;
}
string root;
string key;
string value;
};
//鍵值對(duì)結(jié)構(gòu)體
class SubNode
{
public:
void InsertElement(string key, string value)
{
sub_node.insert(pair<string, string>(key, value));
}
map<string, string> sub_node;
};
//INI文件操作類
class CMyINI
{
public:
CMyINI();
~CMyINI();
public:
int ReadINI(string path); //讀取INI文件
string GetValue(string root, string key); //由根結(jié)點(diǎn)和鍵獲取值
vector<ININode>::size_type GetSize(){ return map_ini.size(); } //獲取INI文件的結(jié)點(diǎn)數(shù)
vector<ININode>::size_type SetValue(string root, string key, string value); //設(shè)置根結(jié)點(diǎn)和鍵獲取值
int WriteINI(string path); //寫(xiě)入INI文件
void Clear(){ map_ini.clear(); } //清空
void Travel(); //遍歷打印INI文件
private:
map<string, SubNode> map_ini; //INI文件內(nèi)容的存儲(chǔ)變量
};
CMyINI.cpp
#include "StdAfx.h"
#include "MyINI.h"
#define INIDEBUG
CMyINI::CMyINI()
{
}
CMyINI::~CMyINI()
{
}
//************************************************************************
// 函數(shù)名稱: TrimString
// 訪問(wèn)權(quán)限: public
// 創(chuàng)建日期: 2017/01/05
// 創(chuàng) 建 人:
// 函數(shù)說(shuō)明: 去除空格
// 函數(shù)參數(shù): string & str 輸入的字符串
// 返 回 值: std::string & 結(jié)果字符串
//************************************************************************
string &TrimString(string &str)
{
string::size_type pos = 0;
while (str.npos != (pos = str.find(" ")))
str = str.replace(pos, pos + 1, "");
return str;
}
//************************************************************************
// 函數(shù)名稱: ReadINI
// 訪問(wèn)權(quán)限: public
// 創(chuàng)建日期: 2017/01/05
// 創(chuàng) 建 人:
// 函數(shù)說(shuō)明: 讀取INI文件,并將其保存到map結(jié)構(gòu)中
// 函數(shù)參數(shù): string path INI文件的路徑
// 返 回 值: int
//************************************************************************
int CMyINI::ReadINI(string path)
{
ifstream in_conf_file(path.c_str());
if (!in_conf_file) return 0;
string str_line = "";
string str_root = "";
vector<ININode> vec_ini;
while (getline(in_conf_file, str_line))
{
string::size_type left_pos = 0;
string::size_type right_pos = 0;
string::size_type equal_div_pos = 0;
string str_key = "";
string str_value = "";
if ((str_line.npos != (left_pos = str_line.find("["))) && (str_line.npos != (right_pos = str_line.find("]"))))
{
//cout << str_line.substr(left_pos+1, right_pos-1) << endl;
str_root = str_line.substr(left_pos + 1, right_pos - 1);
}
if (str_line.npos != (equal_div_pos = str_line.find("=")))
{
str_key = str_line.substr(0, equal_div_pos);
str_value = str_line.substr(equal_div_pos + 1, str_line.size() - 1);
str_key = TrimString(str_key);
str_value = TrimString(str_value);
//cout << str_key << "=" << str_value << endl;
}
if ((!str_root.empty()) && (!str_key.empty()) && (!str_value.empty()))
{
ININode ini_node(str_root, str_key, str_value);
vec_ini.push_back(ini_node);
//cout << vec_ini.size() << endl;
}
}
in_conf_file.close();
in_conf_file.clear();
//vector convert to map
map<string, string> map_tmp;
for (vector<ININode>::iterator itr = vec_ini.begin(); itr != vec_ini.end(); ++itr)
{
map_tmp.insert(pair<string, string>(itr->root, ""));
} //提取出根節(jié)點(diǎn)
for (map<string, string>::iterator itr = map_tmp.begin(); itr != map_tmp.end(); ++itr)
{
#ifdef INIDEBUG
cout << "根節(jié)點(diǎn): " << itr->first << endl;
#endif //INIDEBUG
SubNode sn;
for (vector<ININode>::iterator sub_itr = vec_ini.begin(); sub_itr != vec_ini.end(); ++sub_itr)
{
if (sub_itr->root == itr->first)
{
#ifdef INIDEBUG
cout << "鍵值對(duì): " << sub_itr->key << "=" << sub_itr->value << endl;
#endif //INIDEBUG
sn.InsertElement(sub_itr->key, sub_itr->value);
}
}
map_ini.insert(pair<string, SubNode>(itr->first, sn));
}
return 1;
}
//************************************************************************
// 函數(shù)名稱: GetValue
// 訪問(wèn)權(quán)限: public
// 創(chuàng)建日期: 2017/01/05
// 創(chuàng) 建 人:
// 函數(shù)說(shuō)明: 根據(jù)給出的根結(jié)點(diǎn)和鍵值查找配置項(xiàng)的值
// 函數(shù)參數(shù): string root 配置項(xiàng)的根結(jié)點(diǎn)
// 函數(shù)參數(shù): string key 配置項(xiàng)的鍵
// 返 回 值: std::string 配置項(xiàng)的值
//************************************************************************
string CMyINI::GetValue(string root, string key)
{
map<string, SubNode>::iterator itr = map_ini.find(root);
map<string, string>::iterator sub_itr = itr->second.sub_node.find(key);
if (!(sub_itr->second).empty())
return sub_itr->second;
return "";
}
//************************************************************************
// 函數(shù)名稱: WriteINI
// 訪問(wèn)權(quán)限: public
// 創(chuàng)建日期: 2017/01/05
// 創(chuàng) 建 人:
// 函數(shù)說(shuō)明: 保存XML的信息到文件中
// 函數(shù)參數(shù): string path INI文件的保存路徑
// 返 回 值: int
//************************************************************************
int CMyINI::WriteINI(string path)
{
ofstream out_conf_file(path.c_str());
if (!out_conf_file)
return -1;
//cout << map_ini.size() << endl;
for (map<string, SubNode>::iterator itr = map_ini.begin(); itr != map_ini.end(); ++itr)
{
//cout << itr->first << endl;
out_conf_file << "[" << itr->first << "]" << endl;
for (map<string, string>::iterator sub_itr = itr->second.sub_node.begin(); sub_itr != itr->second.sub_node.end(); ++sub_itr)
{
//cout << sub_itr->first << "=" << sub_itr->second << endl;
out_conf_file << sub_itr->first << "=" << sub_itr->second << endl;
}
}
out_conf_file.close();
out_conf_file.clear();
return 1;
}
//************************************************************************
// 函數(shù)名稱: SetValue
// 訪問(wèn)權(quán)限: public
// 創(chuàng)建日期: 2017/01/05
// 創(chuàng) 建 人:
// 函數(shù)說(shuō)明: 設(shè)置配置項(xiàng)的值
// 函數(shù)參數(shù): string root 配置項(xiàng)的根節(jié)點(diǎn)
// 函數(shù)參數(shù): string key 配置項(xiàng)的鍵
// 函數(shù)參數(shù): string value 配置項(xiàng)的值
// 返 回 值: std::vector<ININode>::size_type
//************************************************************************
vector<ININode>::size_type CMyINI::SetValue(string root, string key, string value)
{
map<string, SubNode>::iterator itr = map_ini.find(root); //查找
if (map_ini.end() != itr)
{
//itr->second.sub_node.insert(pair<string, string>(key, value));
itr->second.sub_node[key] = value;
} //根節(jié)點(diǎn)已經(jīng)存在了,更新值
else
{
SubNode sn;
sn.InsertElement(key, value);
map_ini.insert(pair<string, SubNode>(root, sn));
} //根節(jié)點(diǎn)不存在,添加值
return map_ini.size();
}
//************************************************************************
// 函數(shù)名稱: Travel
// 訪問(wèn)權(quán)限: public
// 創(chuàng)建日期: 2017/01/05
// 創(chuàng) 建 人:
// 函數(shù)說(shuō)明: 遍歷打印INI文件
// 返 回 值: void
//************************************************************************
void CMyINI::Travel()
{
for (map<string, SubNode>::iterator itr = this->map_ini.begin(); itr!= this->map_ini.end(); ++itr)
{
//root
cout << "[" << itr->first << "]" << endl;
for (map<string, string>::iterator itr1=itr->second.sub_node.begin(); itr1!=itr->second.sub_node.end();
++itr1)
{
cout << " " << itr1->first << " = " << itr1->second << endl;
}
}
}
測(cè)試之前INI文件的內(nèi)容:

測(cè)試程序:
CMyINI *p = new CMyINI();
p->ReadINI("Setting.ini");
cout << "\n原始INI文件內(nèi)容:" << std::endl;
p->Travel();
p->SetValue("setting", "hehe", "eheh");
cout << "\n增加節(jié)點(diǎn)之后的內(nèi)容:" << std::endl;
p->Travel();
cout << "\n修改節(jié)點(diǎn)之后的內(nèi)容:" << std::endl;
p->SetValue("kk", "kk", "2");
p->Travel();
p->WriteINI("Setting.ini");
測(cè)試結(jié)果:


五、C++讀寫(xiě)ini文件中的配置信息
ini文件是由若干個(gè)節(jié)(Sction)組成,每個(gè)節(jié)又由若干個(gè)鍵(Key)組成。
1、將文件寫(xiě)入ini文件中,主要使用的函數(shù)是WritePrivateProfileString(LPCWSTR IpAppName,LPCWSTR IpKeyName,LPCWSTR IpString,LPCWSTR IpFileName);
參數(shù)一表示節(jié)的名字,參數(shù)二表示鍵的名字,若為NULL,則刪除整個(gè)節(jié),參數(shù)三表示鍵的值,若為NULL,則刪除這個(gè)鍵,參數(shù)四表示文件名。
#ifndef CONFIG_FILE
#define CONFIG_FILE (_T("Config.ini"))
#endif
TCHAR IniPath[MAX_PATH]={0}
GetModuleFileName(NULL,IniPath,Max_Path);
TCHAR *pFind=_tcsrchr(IniPath,'\\');
if(pFind==NULL)
{
return;
}
*pFind='\0';
CString newIniPath=IniPath;
newIniPath+="\\";
newIniPath+=CONFIG_FILE;
寫(xiě)入........
2、將ini文件中的配置信息讀取出來(lái),主要使用的函數(shù)為 GetPrivateProfileString(LPCWSTR IpAppName,LPCWSTR IpKeyName,LPCWSTR IpDefault,LPCWSTR IpReturnedString,DWORD nSize,LPCWSTR IpFileName)和GetPrivateProfileInt(LPCWSTR IpAppName,LPCWSTR IpKeyName,Int nDefault,LPCWSTR IpFileName);
GetPrivateProfileString:參數(shù)一表示節(jié)的名字,參數(shù)二表示鍵的名字,參數(shù)三表示如果指定的鍵名不存在時(shí)所默認(rèn)的讀取值,參數(shù)四用來(lái)接收讀取的字符串,參數(shù)五指定lpReturnedString指向的緩沖區(qū)的大小 ,參數(shù)六表示文件名。
GetPrivateProfileInt:參數(shù)一表示節(jié)的名字,參數(shù)二表示鍵的名字,參數(shù)三表示如果指定的鍵名不存在時(shí)所默認(rèn)的讀取值,參數(shù)四表示文件名。
TCHAR IniPath[MAX_PATH]={0};
GetModuleFileName(NULL,IniPath,Max_Path);
IniPath[_tcslen(IniPath)-1]='i'
IniPath[_tcslen(IniPath)-2]='n'
IniPath[_tcslen(IniPath)-3]='i'
if(!PathFileExists(IniPath))
{}
讀取...........
相關(guān)文章
關(guān)于背包問(wèn)題的一些理解和應(yīng)用
這篇文章主要介紹了關(guān)于背包問(wèn)題的一些理解和應(yīng)用,本文可以說(shuō)是背包問(wèn)題九講的補(bǔ)充、讀后感,需要的朋友可以參考下2014-08-08
C語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的掃雷游戲
掃雷是電腦上很經(jīng)典的游戲,特意去網(wǎng)上玩了一會(huì),幾次調(diào)試之后,發(fā)現(xiàn)這個(gè)比三子棋要復(fù)雜一些,尤其是空白展開(kāi)算法上和堵截玩家有的一拼,與實(shí)際游戲差別較大,不能使用光標(biāo),下面來(lái)詳解每一步分析2021-10-10
C語(yǔ)言大小端字節(jié)序存儲(chǔ)模式深入解讀
我們知道,當(dāng)編譯器執(zhí)行 “創(chuàng)建變量” 這一代碼時(shí),會(huì)在內(nèi)存中開(kāi)辟空間相應(yīng)的空間來(lái)存儲(chǔ)變量值。而對(duì)于整型變量而言,變量值又是以二進(jìn)制補(bǔ)碼的形式存放的2022-09-09

