C/C++ INI文件操作实现代码

一、INI文件用途:

1、存储程序的初始化信息;
2、存储需要保存的数据信息。

二、INI文件结构:

由节名、键名、键值组成。形式如下:
[节名]
键名 = 键值

备注:一个INI文件,可以用多个节。

三、读取INI文件

1、WritePrivateProfileString

该函数用于向INI文件中写入一个字符串数据。

函数原型如下:

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
);

参数说明:

lpAppName:指定节名,以空终止结尾的字符串。如果INI文件中节名不存在,将创建一个节名。
lpKeyName:键名,以空终止结尾的字符串。如果INI文件中该键名不存在,将创建一个键名。如果该参数为NULL,包括节及节下的所有项目都将被删除。
lpString:写到键值中的数据,以空终止结尾的字符串。
lpFileName:INI文件的名称,以空终止结尾的字符串。指定需要写入数据的INI文件,如果指定的INI文件不存在将创建。

返回值:

如果函数成功将字符串复制到初始化文件,返回值是非零。
如果函数失败,刷新缓存版本的最近访问初始化文件,返回值是零。

2、GetPrivateProfileString

该函数用于获取INI文件中的键值。
函数原型如下:

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
);

参数说明:

lpAppName:指定节名,以空终止结尾的字符串。如果该参数为NULL,函数将复制所有的节名到所指定的缓冲区中。
lpKeyName:键名,以空终止结尾的字符串。如果该参数为NULL,函数将lpAppName节下所有的键名复制到lpReturnedString缓冲区。
lpDefault:默认值,以空终止结尾的字符串。如果获取键值的键名不存在时,返回设置的默认值。
lpReturnedString:用于接受数据的缓冲区。
nSize:以字符为单位表示lpReturnedString缓冲区的大小。
lpFileName:INI文件名称,以空终止结尾的字符串。

返回值:
返回值是字符复制到缓冲区的数量,不包括终止null字符。

3、GetPrivateProfileInt

该函数用于从INI文件中获取整型数据。
函数原型如下:

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
);

参数说明:
lpAppName:节名。
lpKeyName:键名。
nDefault:默认值。
lpFileName:INI文件名称。

返回值:

函数返回实际读取的整数值。

4、GetPrivateProfileSectionNames

该函数用于返回INI文件中的所有节名。
函数原型如下:

DWORD GetPrivateProfileSectionNames(
 LPTSTR lpszReturnBuffer, // address of return buffer
 DWORD nSize, // size of return buffer
 LPCTSTR lpFileName // address of initialization filename
);

参数说明:
lpszReturnBuffer:接受节名的数据缓冲区。
nSize:缓冲区的大小。
lpFileName:INI文件名称。
返回值:
返回值指定数量的字符复制到指定的缓冲,不包括终止null字符。
如果缓冲区没有大到足以包含所有相关的部分名称指定的初始化文件,返回值等于指定的长度nSize - 2。

5、GetPrivateProfileSection

该函数用于获取指定节下的所有的键名和键值。
函数原型如下:

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
);

参数说明:

lpAppName:节名。
lpReturnedString:用于接受数据的缓冲区。
nSize:缓冲区的大小。
lpFileName:INI文件名称。
返回值:
返回值指定数量的字符复制到缓冲区,不包括终止null字符。
如果缓冲区没有大到足以包含所有与指定相关联的键名称和值对部分,返回值等于nSize - 2。

四、C++实现INI文件读写完整代码

CMyINI.h

#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <map>

using namespace std;

//INI文件结点存储结构
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;
};

//键值对结构体
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);									//由根结点和键获取值
	vector<ININode>::size_type GetSize(){ return map_ini.size(); }				//获取INI文件的结点数
	vector<ININode>::size_type SetValue(string root, string key, string value);	//设置根结点和键获取值
	int WriteINI(string path);			//写入INI文件
	void Clear(){ map_ini.clear(); }	//清空
	void Travel();						//遍历打印INI文件
private:
	map<string, SubNode> map_ini;		//INI文件内容的存储变量
};

CMyINI.cpp

#include "StdAfx.h"
#include "MyINI.h"

#define INIDEBUG

CMyINI::CMyINI()
{
}

CMyINI::~CMyINI()
{
}

//************************************************************************
// 函数名称: 	TrimString
// 访问权限: 	public
// 创建日期:		2017/01/05
// 创 建 人:
// 函数说明:		去除空格
// 函数参数: 	string & str	输入的字符串
// 返 回 值: 	std::string &	结果字符串
//************************************************************************
string &TrimString(string &str)
{
	string::size_type pos = 0;
	while (str.npos != (pos = str.find(" ")))
		str = str.replace(pos, pos + 1, "");
	return str;
}

//************************************************************************
// 函数名称: 	ReadINI
// 访问权限: 	public
// 创建日期:		2017/01/05
// 创 建 人:
// 函数说明:		读取INI文件,并将其保存到map结构中
// 函数参数: 	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, ""));
	}	//提取出根节点
	for (map<string, string>::iterator itr = map_tmp.begin(); itr != map_tmp.end(); ++itr)
	{
#ifdef INIDEBUG
		cout << "根节点: " << 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 << "键值对: " << 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;
}

//************************************************************************
// 函数名称: 	GetValue
// 访问权限: 	public
// 创建日期:		2017/01/05
// 创 建 人:
// 函数说明:		根据给出的根结点和键值查找配置项的值
// 函数参数: 	string root		配置项的根结点
// 函数参数: 	string key		配置项的键
// 返 回 值: 	std::string		配置项的值
//************************************************************************
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 "";
}

//************************************************************************
// 函数名称: 	WriteINI
// 访问权限: 	public
// 创建日期:		2017/01/05
// 创 建 人:
// 函数说明:		保存XML的信息到文件中
// 函数参数: 	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;
}

//************************************************************************
// 函数名称: 	SetValue
// 访问权限: 	public
// 创建日期:		2017/01/05
// 创 建 人:
// 函数说明:		设置配置项的值
// 函数参数: 	string root		配置项的根节点
// 函数参数: 	string key		配置项的键
// 函数参数: 	string value	配置项的值
// 返 回 值: 	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;
	}	//根节点已经存在了,更新值
	else
	{
		SubNode sn;
		sn.InsertElement(key, value);
		map_ini.insert(pair<string, SubNode>(root, sn));
	}	//根节点不存在,添加值

	return map_ini.size();
}

//************************************************************************
// 函数名称: 	Travel
// 访问权限: 	public
// 创建日期:		2017/01/05
// 创 建 人:
// 函数说明:		遍历打印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;
		}
	}

}

测试之前INI文件的内容:

测试程序:

CMyINI *p = new CMyINI();
p->ReadINI("Setting.ini");
cout << "\n原始INI文件内容:" << std::endl;
p->Travel();
p->SetValue("setting", "hehe", "eheh");
cout << "\n增加节点之后的内容:" << std::endl;
p->Travel();
cout << "\n修改节点之后的内容:" << std::endl;
p->SetValue("kk", "kk", "2");
p->Travel();
p->WriteINI("Setting.ini");

测试结果:

五、C++读写ini文件中的配置信息

ini文件是由若干个节(Sction)组成,每个节又由若干个键(Key)组成。
1、将文件写入ini文件中,主要使用的函数是WritePrivateProfileString(LPCWSTR IpAppName,LPCWSTR IpKeyName,LPCWSTR IpString,LPCWSTR IpFileName);
参数一表示节的名字,参数二表示键的名字,若为NULL,则删除整个节,参数三表示键的值,若为NULL,则删除这个键,参数四表示文件名。

#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;

写入........

2、将ini文件中的配置信息读取出来,主要使用的函数为 GetPrivateProfileString(LPCWSTR IpAppName,LPCWSTR IpKeyName,LPCWSTR IpDefault,LPCWSTR IpReturnedString,DWORD nSize,LPCWSTR IpFileName)和GetPrivateProfileInt(LPCWSTR IpAppName,LPCWSTR IpKeyName,Int nDefault,LPCWSTR IpFileName);
 GetPrivateProfileString:参数一表示节的名字,参数二表示键的名字,参数三表示如果指定的键名不存在时所默认的读取值,参数四用来接收读取的字符串,参数五指定lpReturnedString指向的缓冲区的大小  ,参数六表示文件名。
GetPrivateProfileInt:参数一表示节的名字,参数二表示键的名字,参数三表示如果指定的键名不存在时所默认的读取值,参数四表示文件名。

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))
{}

读取...........

(0)

相关推荐

  • C++ socket实现miniFTP

    本文实例为大家分享了C++ socket实现miniFTP的方法,供大家参考,具体内容如下 客户端: 服务端: 建立连接 连接使用 TCP 连接,服务器和客户端分别创建自己的套接字一端,服务器等待连接,客户端发起连接(并指定服务器 ip).在两者端口号一致且不被占用的情况下,连接建立.         在整个过程中,服务器对每一个来访的客户端建立一个连接,在客户未请求与服务器断开时,该连接一直存在,用户可以不断向服务器发出请求.(持久性.流水线型连接 )         客户端断开后,关闭客户端

  • C++读取INI配置文件类实例详解

    本文以实例讲解了C++读取配置文件的方法. 一般情况下,我们都喜欢使用ini扩展名的文件作为配置文件,可以读取及修改变量数值,也可以设置新的组,新的变量,本文的实例代码一个是读取INI的定义文件,另一个是CIniFile类实现文件,两者结合,完美实现VC++对INI文件的读写. 用户接口说明:在成员函数SetVarStr和SetVarInt函数中,当iType等于零,则如果用户制定的参数在ini文件中不存在,则就写入新的变量.当iType不等于零,则如果用户制定的参数在ini文件中不存在,就不写

  • c++ minicsv库的编译错误与解决方案

    有一个项目需要写csv文件以呈现数据.Github上有一个关于csv的轻量级读写库minicsv,于是下载之.但是编译example时出现了以下问题: In file included from example.cpp:1:0: minicsv.hpp: In function 'csv::ofstream& operator<<(csv::ofstream&, const T&)': minicsv.hpp:326:38: error: no matching fun

  • C++读写INI配置文件的类实例

    本文实例讲述了C++读写INI配置文件的类.分享给大家供大家参考.具体如下: 1. IniReader.h文件: #ifndef INIREADER_H #define INIREADER_H #include <windows.h> class CIniReader { public: CIniReader(LPCTSTR szFileName); int ReadInteger(LPCTSTR szSection, LPCTSTR szKey, int iDefaultValue); fl

  • C/C++ INI文件操作实现代码

    一.INI文件用途: 1.存储程序的初始化信息: 2.存储需要保存的数据信息. 二.INI文件结构: 由节名.键名.键值组成.形式如下: [节名] 键名 = 键值 备注:一个INI文件,可以用多个节. 三.读取INI文件 1.WritePrivateProfileString 该函数用于向INI文件中写入一个字符串数据. 函数原型如下: BOOL WritePrivateProfileString( LPCTSTR lpAppName, // pointer to section name LP

  • 使用Python中Tkinter模块的Treeview 组件显示ini文件操作

    前言: Tkinter模块的Treeview组件类似于Dev中的treelist控件,但前者还可以当做树控件和表格控件使用,虽然功能可能没有dev和winform控件那么强大,但是在Tkinter中算是比较复杂.用处较多的了. Treeview组件位于ttk模块,该模块自Tk8.5开始引入,如果 Python 未基于 Tk 8.5 编译,只要安装了 Tile 仍可访问本模块.Treeview支持按层次结构展示一组数据项,用excel做了个简单的示意图(如下所示),Treeview 组件左侧可以理

  • Scala文件操作示例代码讲解

    目录 1. 读取数据 1.1 按行读取 1.2 按字符读取 Scala使用source.buffered方法按字符读取文件 一个示例 1.3 读取词法单元和数字 1.4 从URL或者其他源读取数据 1.5 读取二进制文件 2. 写入文件 2.1 使用java.io.PrintWriter类 2.2 使用java.io.FileWriter类 2.3 使用java.io.FileOutputStream类 2.4 几种写入的区别 2.5 使用第三方库 3. Scala序列化和反序列化 3.1 什么

  • C# Ini文件操作实例

    在开源中国看到的操作ini文件的,写的还不看,留着以后用 复制代码 代码如下: using System;using System.IO;using System.Runtime.InteropServices;using System.Text;using System.Collections;using System.Collections.Specialized; namespace wuyisky{ /**//**/ /**//// <summary> /// IniFiles的类 /

  • PHP文件操作实现代码分享

    将数据写或读入文件,基本上分为三个步骤: 1. 打开一个文件(如果存在) 2. 写/读文件 3. 关闭这个文件 l打开文件 在打开文件文件之前,我们需要知道这个文件的路径,以及此文件是否存在. 用$_SERVER["DOCUMENT_ROOT"]内置全局变量,来获得站点的相对路径.如下: $root = $_SERVER["DOCUMENT_ROOT"]; 在用函数file_exists()来检测文件是否存在.如下: If(!file_exists("$r

  • php文件操作实例代码

    先送上一段简单的实例 复制代码 代码如下: <?php if(!is_dir('txt'))//判断txt是否为文件夹目录 { mkdir('txt');//创建名为txt的文件夹目录 $open=fopen('txt/in.txt',"w+");//以读写的方式打开文件 if(is_writable('txt/in.txt'))//如果此文件为可写模式 { if(fwrite($open,"今天是美好的一天,一定要开心哦!<- ->")>0

  • ASP FSO文件操作函数代码(复制文件、重命名文件、删除文件、替换字符串)

    FSO文件(File)对象属性 DateCreated 返回该文件夹的创建日期和时间 DateLastAccessed 返回最后一次访问该文件的日期和时间 DateLastModified 返回最后一次修改该文件的日期和时间 Drive 返回该文件所在的驱动器的Drive对象 Name 设定或返回文件的名字 ParentFolder 返回该文件的父文件夹的Folder对象 Path 返回文件的绝对路径,可使用长文件名 ShortName 返回DOS风格的8.3形式的文件名 ShortPath 返

  • asp.net XML文件操作实现代码

    以前也学过一些这方面的知识,好久都没怎么用了,忘得也差不多,正好现在可以重新巩固一遍,熟悉一下对XML文件的操作. XML(Extensible Markup Language)即可扩展标记语言,它与HTML一样,都是SGML(Standard Generalized Markup Language,标准通用标记语言).Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具. 扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标

  • 使用Python对Csv文件操作实例代码

    csv是Comma-Separated Values的缩写,是用文本文件形式储存的表格数据,比如如下的表格: 就可以存储为csv文件,文件内容是: No.,Name,Age,Score 1,mayi,18,99 2,jack,21,89 3,tom,25,95 4,rain,19,80 假设上述csv文件保存为"test.csv" 1.读文件 如何用Python像操作Excel一样提取其中的一列,即一个字段,利用Python自带的csv模块,有两种方法可以实现: 第一种方法使用read

  • php xml文件操作实现代码(二)

    复制代码 代码如下: <?php //创建一个新的DOM文档 $dom = new DomDocument(); //在根节点创建departs标签 $departs = $dom->createElement('departs'); $dom->appendChild($departs); //在departs标签下创建depart子标签 $depart = $dom->createElement('depart'); $departs->appendChild($depa

随机推荐