想项目开发中终归会用到配置文件,方便改服务器IP端口这些
这个代码适合Key-Value键值对类型的配置文件,我的配置文件是这样的
~~~
VideoServerAddress = 192.168.0.139
VideoServerPort = 8000
VideoClientPort = 2000
LandServerAddress = 183.61.39.156
LandSserverPort = 6041
~~~
下面的这份代码我也是拷贝的,然后稍微改造了一下,我运行试了试,确实可以读配置文件。
首先是h文件
~~~
/**************************************
*日期: 2014-12-5
*目的: 读取配置文件的信息,以map的形式存入
*要求: 配置文件的格式,以#作为行注释,配置的形式是key = value,中间可有空
格,也可没有空格
***************************************/
#ifndef _GET_CONFIG_H_
#define _GET_CONFIG_H_
#define COMMENT_CHAR '#'
#include <string>
#include <map>
using namespace std;
bool ReadConfig(const string & filename, map<string, string> & m);
void PrintConfig(const map<string, string> & m);
#endif
~~~
然后就是Cpp了,重头。
~~~
#include "GetConfig.h"
#include <fstream>
#include <iostream>
using namespace std;
bool IsSpace(char c)
{
if (' ' == c || '\t' == c)
return true;
return false;
}
bool IsCommentChar(char c)
{
if (c == COMMENT_CHAR){
return true;
}else{
return false;
}
}
void Trim(string & str)
{
if (str.empty()) {
return;
}
int i, start_pos, end_pos;
for (i = 0; i < str.size(); ++i) {
if (!IsSpace(str[i])) {
break;
}
}
if (i == str.size()) { // 全部是空白字符串
str = "";
return;
}
start_pos = i;
for (i = str.size() - 1; i >= 0; --i) {
if (!IsSpace(str[i])) {
break;
}
}
end_pos = i;
str = str.substr(start_pos, end_pos - start_pos + 1);
}
bool AnalyseLine(const string & line, string & key, string & value)
{
if (line.empty())
return false;
int start_pos = 0, end_pos = line.size() - 1, pos;
if ((pos = line.find(COMMENT_CHAR)) != -1) {
if (0 == pos) { // 行的第一个字符就是注释字符
return false;
}
end_pos = pos - 1;
}
string new_line = line.substr(start_pos, start_pos + 1 - end_pos); // 预处理,删除注释部分
if ((pos = new_line.find('=')) == -1)
return false; // 没有=号
key = new_line.substr(0, pos);
value = new_line.substr(pos + 1, end_pos + 1- (pos + 1));
Trim(key);
if (key.empty()) {
return false;
}
Trim(value);
return true;
}
// 读取数据
bool ReadConfig(const string & filename, map<string, string> & m)
{
m.clear();
ifstream infile(filename.c_str());
if (!infile) {
cout << "file open error" << endl;
return false;
}
string line, key, value;
while (getline(infile, line)) {
if (AnalyseLine(line, key, value)) {
m[key] = value;
}
}
infile.close();
return true;
}
// 打印读取出来的数据
void PrintConfig(const map<string, string> & m)
{
//ofstream fout("e:\\Config.txt");
map<string, string>::const_iterator mite = m.begin();
for (; mite != m.end(); ++mite) {
cout << mite->first << "=" << mite->second << endl;
/*// 把内容输出到新的文件里面去
fout << mite->first << "=" << mite->second << endl;*/
}
//fout.close();
}
int main()
{
string m_sPath = "e:\\LandClient.conf";
map<string,string> m_mapConfig;
ReadConfig(m_sPath,m_mapConfig);
PrintConfig(m_mapConfig);
system("pause");
return 0;
}
~~~
这份代码我觉得精髓就在与stl的运用,确实不错。
下面是运行的结果:
![](https://box.kancloud.cn/2016-08-19_57b6ce7940bed.jpg)
对了 这是原文的链接:http://www.cnblogs.com/tzhangofseu/archive/2011/10/02/2197966.html
感觉这份代码的函数封装以及map的运用确实不错
- 前言
- C++读取配置文件
- 结构体内存对齐后所占内存空间大小的计算
- do{}while(0)的妙用
- Cocos2dx实现翻牌效果(CCScaleTo与CCOrbitCamera两种方式)
- C++的error LNK2019: 无法解析的外部符号编译错误
- Java使用JNI调用C++的完整流程
- strupr与strlwr函数的实现
- strcat函数实现
- Windows上VS使用pthread重温经典多线程卖票(pthreads-w32-2-8-0-release.exe)(windows上使用pthread.h)
- pthread的pthread_join()函数理解实验
- 顺序存储结构和链式存储结构的选择
- C语言冒泡排序
- VS看反汇编、寄存器、内存、堆栈调用来学习程序设计
- 快速排序
- C++的构造函数初始化列表
- fatal error C1083: 无法打开包括文件: “SDKDDKVer.h”: No such file or directory
- C++实现简单的String类