c++ 实现对配置文件的读写 根据windows API 函数简单改写

  

c++ stl实现对配置文件的读写 根据windows API WritePrivateProfileString,GetPrivateProfileString简单改写

文章转自:http://blog.csdn.net/woaiyu6464/article/details/6162486

 

 

#ifndef _CONFIG_H__
#define _CONFIG_H__
#include <string>
#include <fstream>
using namespace std;

class Config
{
public:
    Config( ){};
    ~Config( ){};
    void open(string filename)
    {
        fileName =new string(filename.c_str());
    }
 bool WritePrivateProfileString(const char *strSectionName,const char *strKeyName,const char *strValue,const char *strFileName)
 {
  bool ret = false;
  
  //section是null则直接返回false
  string strvalue = strValue;
  if(strvalue.empty())
  {
   return false;
  }
  
  bool flagFindSection = false;//是否找到了section
  int pos = 0;
  
  string strSection = "[";
  strSection+=strSectionName;
  strSection+="]";
  string strKey = strKeyName;
  strKey+="=";
  
  ifstream Readfile;
        Readfile.open(strFileName);
        if(!Readfile.is_open())
  {
      Readfile.close();
   return false;
        }
        
  ofstream file;
  file.open (strFileName,ios::in | ios::out);
 //       file.open (strFileName);
  if(!file.is_open())
  {
      Readfile.close();
      file.close();
   return false;
        }
        string line;
  while (!Readfile.eof())
  {
   getline(Readfile,line); //读取第一行数据
   if(line.find(strSection)!=0) //如果没有找到section就一直读写下去
   {
    file<<line<<"/n"; 
   }
   else
   {   //找到section
    flagFindSection = true;
    ret = true;
    
    file<<line<<"/n";
    getline(Readfile,line);
    //如果没有找到keyname或则没有读取到下一个section或者没有读取到结尾就一直找下去
    while(line.find(strKey) != 0 && line.find("[") != 0 && !Readfile.eof())
    {
     file<<line<<"/n";
     getline(Readfile,line);
    }
                if(line.find(strKeyName) == 0)//查找到key
    {
        string note = "";//注释
        string nbsp = "";//空格
     if(line.find("#") != string::npos) //找到注释语句
     {
        note = line.substr(line.find("#"));
        line = line.substr(0,line.find("#"));//取得注释号前面的字符串
        if(line.find_last_of(" ") != string::npos)//keyname的值与注释之间有空格
                       {
                            nbsp = line.substr(line.find_last_not_of(" ")+1);//把空格取出来存到nbsp中
                       }
                    }
     line = line.substr(0,line.find("=")+1);     
     line+=strvalue;
     line+=nbsp;
     line+=note;
     file<<line<<"/n";
     getline(Readfile,line);
     //剩余行写入流中
     while(!Readfile.eof())
     {
      
      file<<line<<"/n";
      getline(Readfile,line);
     }
     file<<line<<"/n";
     return true;
     break;
    }
    else if(line.find("[") == 0) //读取到下一个section了 说明上一个section里面没有keyname 我们就把数据写到这个section中
    {
          string maName=strKeyName;
          string maValue=strValue;
          file<<line<<"/n";
          if(!maName.empty() && !maValue.empty())
          {
            maName+="=";
            maName+=maValue;
            file<<maName<<"/n";
                      }
                      getline(Readfile,line);
                      //剩余行写入流中
                      while(!Readfile.eof())
       {      
       file<<line<<"/n";
       getline(Readfile,line);
       }
      file<<line<<"/n";
                     file.close();
                     Readfile.close();
                return true;
                }
                else if(Readfile.eof())//读取数据到结尾了。。 说明没有找到keyname 那我们就把数据写在最后面
    {
        string maName=strKeyName;
              string maValue=strValue;
    //          file<<line<<"/n";
          if(!maName.empty() && !maValue.empty())
          {
            maName+="=";
            maName+=maValue;
            file<<maName<<"/n";
                      }
        file.close();
                    Readfile.close();
     return true;
                }
    
   }
  }
  if(!flagFindSection)//若没有查到section  那就在section,keyname,strvalue都不为空的情况下把数据写到结尾
  {
 //   file<<line<<"/n";
    string maName=strKeyName;
          string maValue=strValue;
    string sTemp=strSectionName;
    if(!sTemp.empty() && !maName.empty() && !maValue.empty())
    {
        file<<strSection<<"/n";
        maName+="=";
              maName+=maValue;
              file<<maName<<"/n";
  
          }  
    file.close();
    Readfile.close();
    return true;
        }
   
  file.close();
  Readfile.close();
  return ret;
  
 }
 string GetPrivateProfileString(const char *strSectionName,const char *strKeyName,const char *strFileName)
 {
 
  string reValue;
//  reValue = *fileName;
//  return reValue;
  reValue = "oxfalse";
  ifstream Readfile;
  Readfile.open(strFileName);
  if(!Readfile.is_open())//打不开文件  返回0
  {
   Readfile.close();
   return reValue;
  }
  string strSection="[";
  strSection+=strSectionName;
  strSection+="]";
  string strKey=strKeyName;
  strKey+="=";
  while(!Readfile.eof())
  {
   string line;
   getline(Readfile,line); //读取第一行数据
   if(line.find(strSection) == 0) //找到section
   {
    getline(Readfile,line);
    while(line.find(strKey) != 0 && line.find("[") != 0 && !Readfile.eof())
    {
     getline(Readfile,line);
    }
    if(line.find(strKey) == 0)
    {
     reValue = line.substr(line.find("=")+1);
     if(reValue.find("#") != string::npos)    //如果查找到"#" 就去掉包括“#”号后面的字符串
     {
            reValue = reValue.substr(0,reValue.find("#"));
                    }
                    int lv = reValue.find_last_not_of(' ');//查找最后一位不为空格字符的index
                    reValue=reValue.substr(0,lv);//去掉字符串后面的空格
     Readfile.close();
     return reValue;
    }
   }
  }
  Readfile.close();
  return reValue;
 }
private:
    string *fileName;
};

#endif
/*
配置文件格式如下
#注释
[section1]
key1=value1  #注释
key2=value2  #注释
......

[section2]
key1=value1
key2=value2
*/
/*
#include <iostream>
#include "Config.h"
using namespace std;
int main()
{
    Config file;
    bool ok = file.WritePrivateProfileString(“主节点名称”,“子节点名称”,“子节点的值”,“文件路径”);  //写入 成功返回true
    if(ok)
    {
        .....................
    }
    
    string str = file.GetPrivateProfileString("主节点名字",“子节点名称”,“文件路径”);//获取 如果失败返回 “oxfalse”
    if(str != "oxfalse")
    {
        ....................
    }

你可能感兴趣的:(c++ 实现对配置文件的读写 根据windows API 函数简单改写)