LINUX C++读配置文件

重温C++
这篇最后部分的代码只是完成了OCCI接口的实现,可以向多个ORA数据库批量执行指定的SQL;
这次我们完成读取配置文件,就是多个数据库连接信息的配置文件。
类似以下的格式 KEY=VAULE 并且换行来区分不同的数据库连接信息,里面使用#来表示注解

dbname=sharkdb
classA=TEST
classB=PLPM
classC=JN
user=scott
passwd=123456
conn=192.168.2.21:1521/SHARKDB
#2232

dbname=sharkdb
classA=DEV
classB=PLPM
classC=JN
user=scott
passwd=123456
conn=192.168.2.22:1521/SHARKDB


dbname=sharkdb
classA=PRODUC
classB=PLPM
classC=JN
user=scott
passwd=123456
conn=192.168.2.23:1521/SHARKDB
#include 
#include 
#include 
#include 
#include 
#include 

这里多引入了fstream 和 vector 以及cstdlib 三个库。前两个是C++STL库,后面是C库。
随后定义个结构体来表达配置文件的数据结构。

   struct stc_dbconf
    {
        string dbname;
        string classA;
        string classB;
        string classC;
        string User;
        string Password;
        string Connect;
    };

接下来我们定义并实现读取配置文件函数

void Load_DbConf(vector <stc_dbconf> &dblist);
int main(int argc, char** argv) //sqlid,classA,classB,classC,dbname
{     
    vector <stc_dbconf> dbconf_vector;   /*定义结构体数组*/
    Load_DbConf(dbconf_vector);
        
    for (int i=0;i<dbconf_vector.size();i++)
    {
       cout<<"Dbname: "<<dbconf_vector[i].dbname<<endl;
       cout<<"ClassA: "<<dbconf_vector[i].classA<<endl;
       cout<<"ClassB: "<<dbconf_vector[i].classB<<endl;
       cout<<"ClassC: "<<dbconf_vector[i].classC<<endl;
       cout<<"User: "<<dbconf_vector[i].User<<endl;
       cout<<"Password: "<<dbconf_vector[i].Password<<endl;
       cout<<"Connect: "<<dbconf_vector[i].Connect<<endl;
       cout<<endl;
       cout<<endl;   
    }
}    

这是主函数,简化了调用。读取配置文件函数参数是结构体数组,并地址传递。下面是函数的实现!

void Load_DbConf(vector<stc_dbconf> &dblist) 
{
     
    char linebuf[1024];             //定义个行字符数组
    int position=0;                 //等号的位置 =
    int linebuf_size=0;            //实际读取行大小

    stc_dbconf lv_dbconf;         //定义个配置文件本地结构体变量
    string key;                   //KEY字符串变量
    string value;                //VALUE字符串变量
    string tmp_line;             //临时行变量
    ifstream db_config_file;     //配置文件变量
    
      db_config_file.open("db.conf",ios::in);  //只读模式打开程序当前目录下的配置文件  
      if(db_config_file==NULL)     
      { 
          cout<<"Open db.conf file failed"<<endl; 
          exit(1);                      //使用EXIT(1) C函数不得不调用CSTLIB.H
      }
      
      while(!db_config_file.eof())    //如果没有读到文件结束就一直循环下去
      {

          
            db_config_file.getline(linebuf,1024);   //读入一行,最大1024个字符
            
                                                   //首字符非注解#,非换行,非回车,非空白   
            if((linebuf[0]=='#')||(linebuf[0]=='\0')||(linebuf[0]=='\r')||(linebuf[0]=='\n'))
            {
                  if (lv_dbconf.Connect.size()>0) //配置变量是有值的话就加入数组后清空
                  {
                      dblist.push_back(lv_dbconf);
                      lv_dbconf.Connect.clear();
                      lv_dbconf.Password.clear();
                      lv_dbconf.User.clear();
                      lv_dbconf.classA.clear();
                      lv_dbconf.classB.clear();
                      lv_dbconf.classC.clear();
                      lv_dbconf.dbname.clear();
                  }                
               continue;  
            }
            
            tmp_line=linebuf;  //把字符数组复制到自符串变量中,便于操作。
            linebuf_size=tmp_line.size(); //获得实际长度
            position = 0;
            for ( int i=0;i<linebuf_size;i++)
            {
              if(tmp_line[i]=='=')     //找出等号在字符串中的位置
              {
                position = i;  
                break;
              }   
            }
           key.clear();
           key.append(tmp_line,0,position); //KEY值是在等号前
           value.clear();
           if(key=="dbname") //判断各个KEY
             {             //把字符串等号后的值赋值到VALUE中
                  value.append(tmp_line,position+1,linebuf_size-7);  //+1,-7 是定位
                  lv_dbconf.dbname=value; //把VALUE 赋值到结构变量对应属性中。
                  continue; //继续读下一行,跳过后面的判断
              }               
           if(key== "classA")                   
                {
                  value.append(tmp_line,position+1,linebuf_size-6);  
                  lv_dbconf.classA=value;
                  continue;                   
                }                                  
           if(key== "classB")                   
                {
                  value.append(tmp_line,position+1,linebuf_size-6); 
                  lv_dbconf.classB=value;
                  continue;                   
                }                                  
           if(key== "classC")                   
                {
                  value.append(tmp_line,position+1,linebuf_size-6); 
                  lv_dbconf.classC=value;
                  continue;                   
                }                                  
            if(key== "user")                   
                {
                  value.append(tmp_line,position+1,linebuf_size-5);
                  lv_dbconf.User=value;
                  continue;                   
                }                                 
            if(key== "passwd")                   
                {
                  value.append(tmp_line,position+1,linebuf_size-7);
                  lv_dbconf.Password=value;
                  continue;                   
                }                                  
            if(key== "conn")                   
                {
                  value.append(tmp_line,position+1,linebuf_size-5); 
                  lv_dbconf.Connect=value;
                  continue;                   
                }                             
      }
         if (lv_dbconf.Connect.size()>0)  //最后一个也要判断一下,并把它放进数组中。
          {
              dblist.push_back(lv_dbconf);
              lv_dbconf.Connect.clear();
              lv_dbconf.Password.clear();
              lv_dbconf.User.clear();
              lv_dbconf.classA.clear();
              lv_dbconf.classB.clear();
              lv_dbconf.classC.clear();
              lv_dbconf.dbname.clear();
          }
      
      db_config_file.close(); //关闭文件
      
 }

使用C++的数组 字符串 文件流 为加结构体 是比较简单容易读取配置文件的。

你可能感兴趣的:(C/C++)