怎么向ini配置文件加入新的Section?

mfcdeclare 2006-10-19 11:36:56
假如,原配置文件中没有[VERB]这个段,
我想通过程序来加上这个段,能有对应的API吗?

比如,原来的配置文件格式如下:
[AAA]
NAME=li
AGE=18
[BBB]
SCORE=80


在原基础上,用程序能否实现如下格式的配置文件?
[AAA]
NAME=li
AGE=18
[BBB]
SCORE=80
[VERB]
Count=5


好象没有这样的API?

谢谢
...全文
351 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
onestation 2006-10-20
  • 打赏
  • 举报
回复

/*******************************************************************************
函数名称: CConfFile::Load
描 述 : 读取输入的INI文件内容
调用函数:
调用者 :
输入参数: const char * filename 文件名称
输出参数:
返回值 : void
备注 :
*******************************************************************************/
bool Load(const char * filename)
{
m_strFileName = filename;

char szBuf[1024];

fstream file;
file.open(m_strFileName.c_str(), std::ios_base::in);
if ( file.fail() )
{
return false;
}

while( file.getline(szBuf, 1024) )
{
string strTemp = szBuf;
LoadLineData(strTemp);
}

file.close();

return true;

}


bool Save(char * filename=0)
{
char * outfilename = filename;
if ( filename == 0 )
outfilename = (char*)m_strFileName.c_str();

//保存
fstream file;
file.open(outfilename, std::ios_base::out);
if ( file.fail() )
return false;

file.clear();

//获取数据字符串
string strData;

vector<ClassData>::iterator VI;
for(VI=m_Data.begin(); VI!=m_Data.end(); VI++)
{
strData += "[";
strData += (*VI).m_sClass;
strData += "]\n";

map<string, string> * pKeyMap = &((*VI).m_Pair);
map<string, string>::iterator MI;
for (MI=pKeyMap->begin(); MI!=pKeyMap->end(); MI++)
{
strData += (*MI).first;
strData += "=";
strData += (*MI).second;
strData += "\n";
}
}

//写到文件
file.write(strData.c_str(), (int)strData.size());

file.close();

return true;
}

/*******************************************************************************
函数名称: CConfFile::Find
描 述 : 查询某类中的某个键所对应的值
调用函数:
调用者 :
输入参数: const string sClass 类名, 不区分大小写
const string sKey 键名, 不区分大小写
string& sValue 健值, 传入缺省值, 传出新值
输出参数:
返回值 : void
备注 :
*******************************************************************************/
void * Find(const char * sClass,
const char * sKey)
{
string strSection = sClass;
string strKey = sKey;

LowerCase(strSection);
LowerCase(strKey);

vector<ClassData>::iterator VI;
for(VI=m_Data.begin(); VI!=m_Data.end(); VI++)
{
if ( (*VI).m_sClass == strSection)
{
return (void*)(((*VI).m_Pair)[strKey].c_str());
break;
}
}

return 0;

}

/*******************************************************************************
函数名称: CConfFile::GetString
描 述 : 查询某类中的某个键所对应的字符串值
调用函数:
调用者 :
输入参数: const char * sClass 类名, 不区分大小写
const char * sKey 键名, 不区分大小写
输出参数:
返回值 : char * 字符串表示的Key值
备注 :
*******************************************************************************/
char * GetString(const char * sClass, const char * sKey)
{
void * pValue = Find(sClass, sKey);
return (char*)pValue;
}

long GetInteger(const char * sClass, const char * sKey)
{
void * pValue = Find(sClass, sKey);
if ( pValue == 0) return 0;
return atol((char*)pValue);
}

double GetFloat(const char * sClass, const char * sKey)
{
void * pValue = Find(sClass, sKey);
if ( pValue == 0) return 0;
return atof((char*)pValue);
}


//如果没有Section则添加
//如果没有Key则添加
//修改Key值
void SetString(const char * sClass, const char * sKey,
const char * sValue)
{
//无效地址
if ( sClass == 0 || sKey == 0 || sValue == 0) return;

string strSection = sClass;
string strKey = sKey;
string strValue = sValue;

//Section和Key名不能为空
if ( strSection.empty() || strKey.empty() ) return;

vector<ClassData>::iterator VI;
for(VI=m_Data.begin(); VI!=m_Data.end(); VI++)
{
if ( strSection == (*VI).m_sClass )
{
(*VI).m_Pair[strKey] = sValue;
return;
}
}

//添加section
ClassData data;
data.m_sClass = strSection;
data.m_Pair[strKey] = sValue;
m_Data.push_back(data);
}

void SetInteger(const char * sClass, const char * sKey, long lValue)
{
char szBuf[256];
memset(szBuf, 0, 256);
sprintf(szBuf, "%d", lValue);
SetString(sClass, sKey, szBuf);
}

void SetFloat(const char * sClass, const char * sKey, double dValue)
{
char szBuf[256];
memset(szBuf, 0, 256);
sprintf(szBuf, "%f", dValue);
SetString(sClass, sKey, szBuf);
}

}; //class

#endif //__CConfFile_H__

onestation 2006-10-20
  • 打赏
  • 举报
回复
//windows和linux通用的ini文件读写类
/*******************************************************************************
*Copyright (c) All rights reserved
*文件名称:ConfFile.h
*模 块 名:通用
*功能描述:配置文件(INI文件)读操作
*当前版本:1.0
*作 者:
*完成日期:
*取代版本:
*原作者 :
*完成日期:
*修改记录:
* 日期 版本 作者 修改描述
********************************************************************************
*******************************************************************************/
#ifndef __CConfFile_H__
#define __CConfFile_H__

#include <string>
#include <map>
#include <vector>
using std::string;
using std::map;
using std::vector;

#include <stdio.h>
#include <fstream>
using std::fstream;

#pragma warning( disable : 4996)
/**
* 本类处理配置文件。
* 配置文件的格式和windows的INI文件一样:
* [class]
* key1 = value1
* key2 = value2
* [class2]
* key1 = value1
* key2 = value2
*/

class CConfFile
{
public:
// CConfFile(void);
// virtual ~CConfFile(void);
// //从配置文件读入数据
// bool Load(const char * filename);
// bool Save(char * filename=0);
// //查询某类中的某个键所对应的值
// void * Find(const char * sClass,
// const char * sKey);
//
// char * GetString(const char * sClass, const char * sKey);
// long GetInteger(const char * sClass, const char * sKey);
// double GetFloat(const char * sClass, const char * sKey);
//
// void SetString(const char * sClass, const char * sKey, const char * sValue);
// void SetInteger(const char * sClass, const char * sKey, long lValue);
// void SetFloat(const char * sClass, const char * sKey, double dValue);
//protected:
// //添加一行数据
// void LoadLineData(string &str);
// string & Trim(string &str);
// string & LowerCase(string &str);

protected:
//数据结构:保存Section和它所包括的所有Key值
struct ClassData
{
string m_sClass; //类名
map<string, string> m_Pair;//键-值表

bool operator == (const ClassData& r)const
{
if( &r==this ) return true;
return (m_sClass == r.m_sClass) &&
(m_Pair == r.m_Pair);
};

bool operator != (const ClassData& r)const
{
return !(*this == r);
}

};

//数据对象
vector< ClassData > m_Data;

//文件名称
string m_strFileName;
//};


public:

CConfFile(void){};
virtual ~CConfFile(void){};

protected:
/*******************************************************************************
函数名称: CConfFile::Trim
描 述 : 清除字符串前后的空格
调用函数:
调用者 :
输入参数: string &str 需要清除的字符串
输出参数:
返回值 : string &清除后的字符串
备注 :
*******************************************************************************/
string & Trim(string &str)
{
string::size_type pos;

pos = str.find_first_not_of(' ');
if (string::npos!=pos)
{
str.erase(0, pos);
}

pos = str.find_last_not_of(' ');
if (string::npos!=pos)
{
str.erase(pos+1, str.length());
}

return str;
}

/*******************************************************************************
函数名称: CConfFile::LowerCase
描 述 : 将字符串所有大写字符转化为小写
调用函数:
调用者 :
输入参数: string &str 需要修改的字符串
输出参数:
返回值 : string &转换后的字符串
备注 :
*******************************************************************************/
string & LowerCase(string &str)
{
char * pTemp = (char*)str.c_str();
char count = 'a' - 'A';
while ( *pTemp != 0 )
{
if( *pTemp>='A' && *pTemp<='Z' )
{
*pTemp += count;
}
pTemp++;
}

return str;
}

/*******************************************************************************
函数名称: CConfFile::LoadLineData
描 述 : 分析一行INI文件数据,注释丢弃,保存Section和Key值
调用函数:
调用者 :
输入参数: string &str 输入的行数据
输出参数:
返回值 : void
备注 :
*******************************************************************************/
void LoadLineData(string &strLine)
{
string::size_type pos1;
string::size_type pos2;

Trim(strLine);
//是否是注释
pos1 = strLine.find(';');
if ((string::npos != pos1) && (pos1 == 0) )
{
return;
}

//是否是Key
pos1 = strLine.find('=');
if ((string::npos != pos1) && //是否有=号存在
(pos1 != 0) && //等号的位置不等于0
(m_Data.size() > 0)) //已经有Section存在
{
string strKey = strLine.substr(0, pos1);
string strValue = strLine.substr(pos1+1, strLine.length()-pos1-1);

Trim(strKey);
Trim(strValue);
LowerCase(strKey);

m_Data[m_Data.size()-1].m_Pair[strKey] = strValue;

return;
}

//是否是Section
pos1 = strLine.find('[');
pos2 = strLine.find(']');
if ((string::npos != pos1) && (string::npos != pos2))
{
string strSection = strLine.substr(pos1+1, pos2-pos1-1);
LowerCase(strSection);
//添加一个ClassData
ClassData data;
data.m_sClass = strSection;
m_Data.push_back(data);
return;
}

//其他类型的行
}

public:
mfcdeclare 2006-10-20
  • 打赏
  • 举报
回复
楼上这样的方法不行吧。

你这样写,是在[VERB]这个段,存在的时候,是可以的。

但如果不存在,这样写,无效
zhoujie20153 2006-10-20
  • 打赏
  • 举报
回复
在WINCE下也没有呀,实现类似WritePrivateProfileString的功能还是比较容易吧
veryfat 2006-10-20
  • 打赏
  • 举报
回复
真正难的问题是:如果不使用这个api函数实现读写ini文件的功能?

在做linux下的程序,也想使用ini文件来放配置信息,但linux没有类似WritePrivateProfileString的函数,要自己写。

veryfat 2006-10-20
  • 打赏
  • 举报
回复
WritePrivateProfileString会自动生成段的。 我一直这样用。
mfcdeclare 2006-10-20
  • 打赏
  • 举报
回复
to imzhjy(无罪)

个人觉得,你的话太多了。

你怎么知道我没试过?!

正是因为我试过,没有结果,才在这里提问的(只是因为我没有看到这一新的SECTION,事实已经写进去了)。

对你这种,随便猜疑别人、妄下评论的人,我表示非常的不满和鄙视!!!

你算个什嘛东西。。

一会结贴。
先感谢一下kevin_darkelf() 、
wmquan() 、qinzhen228() 、gezhi_dove(gezhi)

虽然分不多,但表达我对你们提醒帮助的謝意! 一会结貼。
qinzhen228 2006-10-20
  • 打赏
  • 举报
回复
完全可以的啊
imzhjy 2006-10-20
  • 打赏
  • 举报
回复
楼主,对别人提供的解决方法,你要试试才说行不行,是对别人劳动成果的尊重.
呵呵,没有恶意,提醒一下.路过
烨炜带火 2006-10-20
  • 打赏
  • 举报
回复
CString temp;
temp.Format("%d",5);
::WritePrivateProfileString("VERB","COUNT",temp,"config.ini");
这种方法正确
wmquan 2006-10-20
  • 打赏
  • 举报
回复
怎么可能,那你原来的配置都是手写的?
要是没有字段的话会自动添加,有的话会覆盖
kevin_darkelf 2006-10-19
  • 打赏
  • 举报
回复
CString temp;
temp.Format("%d",5);
::WritePrivateProfileString("VERB","COUNT",temp,"config.ini");

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧