C++产品开发讲座-(三)常⽤组件1-应⽤配置
应⽤参数较多,往往需⽤⼀个或多个配置文件进⾏储存
配置文件的保存与读取⽅法,尽可能简单
避免逐参数赋值,参数多了,发⽣了版本升级,功能修改
往往容易造成修改遗漏使得配置文件对不上
不好的例子1
bool readDotCfg(ParamDot& param)
{
std::string file_cfg = "./config/dot.cfg";
std::string line;
std::ifstream ifile(file_cfg, std::ios::in);
if (!ifile)
{
qDebug() << "file not found:" << file_cfg.c_str();
return false;
}
while (std::getline(ifile, line))
{
std::string key;
std::string val;
if (!parseKeyVal(line, key, val)) continue;
if (key == "positive") param.positive = std::atoi(val.c_str());
if (key == "height0") param.height0 = std::atof(val.c_str());
if (key == "height0_row") param.height0_row = std::atof(val.c_str());
if (key == "stagger0_col") param.stagger0_col = std::atof(val.c_str());
if (key == "p2r_stagger") param.p2r_stagger = std::atof(val.c_str());
if (key == "p2r_height") param.p2r_height = std::atof(val.c_str());
if (key == "row_s") param.row_s = std::atoi(val.c_str());
if (key == "row_e") param.row_e = std::atoi(val.c_str());
if (key == "col_s") param.col_s = std::atoi(val.c_str());
if (key == "col_e") param.col_e = std::atoi(val.c_str());
if (key == "th_gray_min") param.th_gray_min =
(uint8_t)std::atoi(val.c_str());
}
param.printInfo();
return true;
}
不好的例子2
bool Params::load(const std::string &file_config)
{
QFile qfile(QString::fromStdString(file_config));
if (!qfile.exists())
{
dh_url = "rtsp:
channel=1&subtype=0";
save_dh = true;
arcing_port = "COM1";
th_arcing = 0;
default_height = 0;
default_stagger = 0;
th_stagger_min = -400;
th_stagger_max = 400;
th_height_min = 6000;
th_height_max = 4000;
QJsonObject jobj_root;
QJsonObject jobj;
jobj.insert("dh_url", dh_url.c_str());
jobj.insert("flag_record_dh", save_dh);
jobj.insert("arcing_port", arcing_port.c_str());
jobj.insert("th_arcing", th_arcing);
jobj.insert("default_height", default_height);
jobj.insert("default_stagger", default_stagger);
jobj.insert("th_stagger_min", th_stagger_min);
jobj.insert("th_stagger_max", th_stagger_max);
jobj.insert("th_height_min", th_height_min);
jobj.insert("th_height_max", th_height_max);
jobj_root.insert("app", jobj);
QJsonDocument jdoc;
jdoc.setObject(jobj_root);
QByteArray bytes = jdoc.toJson(QJsonDocument::Indented);
if (!qfile.open(QIODevice::WriteOnly | QIODevice::Text))
{
return false;
}
qfile.write(bytes);
qfile.close();
}
else
{
qfile.open(QIODevice::ReadOnly | QIODevice::Text);
QByteArray bytes = qfile.readAll();
QJsonDocument jdoc = QJsonDocument::fromJson(bytes);
if (!jdoc.isObject())
{
return false;
}
QJsonObject obj_root = jdoc.object();
if (obj_root.empty())
{
return false;
}
QJsonObject obj = obj_root.take("app").toObject();
dh_url = obj.take("dh_url").toString().toStdString();
save_dh = obj.take("save_dh").toBool();
arcing_port = obj.take("arcing_port").toString().toStdString();
th_arcing = obj.take("th_arcing").toInt();
default_height = obj.take("default_height").toDouble();
default_height = obj.take("default_height").toDouble();
default_stagger = obj.take("default_stagger").toDouble();
th_stagger_min = obj.take("th_stagger_min").toDouble();
th_stagger_max = obj.take("th_stagger_max").toDouble();
th_height_min = obj.take("th_height_min").toDouble();
th_height_max = obj.take("th_height_max").toDouble();
}
printData();
return true;
}
好的例子
struct Demo
{
uint32_t val_int = 1;
float val_float = 9.9;
std::string val_str = "test";
std::array<std::string, 3> arr_str = {
"str1", "str2", "str3"};
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Demo, val_int, val_float, val_str, arr_str)
};
template <class T>
void printObject(T&& obj)
{
nlohmann::json json_disp;
nlohmann::to_json(json_disp, obj);
printf("Data: %s\n", json_disp.dump(4).c_str());
}
template <class T>
bool loadJsonFileToObject(const std::string& file_json, T&& obj)
{
std::ifstream ifile(file_json);
if (!ifile.good()) return false;
try
{
nlohmann::json json_obj;
ifile >> json_obj;
nlohmann::from_json(json_obj, obj);
}
catch(const std::exception& e)
{
printf("load failed: %s\n", e.what());
return false;
}
printf("load done, ");
print(obj);
return true;
}
template <class T>
bool saveObjectToJsonFile(const std::string& file_json, T&& obj)
{
std::ofstream ofile(file_json);
if (!ofile.good()) return false;
nlohmann::json json_obj;
nlohmann::to_json(json_obj, obj);
ofile << json_obj.dump(4) << std::endl;
return true;
}
Demo data;
std::cout << loadJsonFileToObject("./demo.json", data) << std::endl;
std::cout << saveObjectToJsonFile("./dump.json", data) << std::endl;