重温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++的数组 字符串 文件流 为加结构体 是比较简单容易读取配置文件的。