#include <iostream>
#include "include/yaml.h"
#include<fstream>
#include <cstring>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
/*
用新的字符(字符串)替换旧的字符(字符串)
*/
std::string& replace_all_distinct(std::string& str,const std::string& old_value,const std::string& new_value)
{
for(std::string::size_type pos(0); pos!=std::string::npos; pos+=new_value.length())
{
if((pos=str.find(old_value,pos))!=std::string::npos)
{
str.replace(pos,old_value.length(),new_value);
}
else
{
break;
}
}
return str;
}
/*
作用: 以字符(子字符串)delim 分割字符串s
参数:delim 子字符,如'\n'
s 从文件中读出来的字符串
*/
std::vector<std::string> StringSplit2(const std::string& s, const std::string& delim)
{
std::vector<std::string> elems;
size_t pos = 0;
//字符串长度
size_t len = s.length();
//字符(子字符串)长度
size_t delim_len = delim.length();
if (delim_len == 0) return elems;
//开始搜索查找,直到字符串末尾
while (pos < len)
{
//在字符串s中搜索是否有子字符串,有则返回相应位置指针。
int find_pos = s.find(delim, pos);
//如果没找到
if (find_pos < 0)
{
elems.push_back(s.substr(pos, len - pos));
break;
}
//如果找到,截取从pos 到find_pos 的字符串。
elems.push_back(s.substr(pos, find_pos - pos));
pos = find_pos + delim_len;
}
return elems;
}
/*
作用: 从filePath 文件中读出相应内容,并返回
*/
string ReadYamlFile(string& filePath)
{
string strData="";
const char * p8File = (char*)filePath.c_str();
FILE *fp;
fp = fopen(p8File,"r");
if(fp == NULL)
{
cout<<"cannot read file, open error"<<endl;
return "false";
}
fseek(fp,0,SEEK_END);//将文件内部的指针指向文件末尾
long lsize=ftell(fp);//获取文件长度,(得到文件位置指针当前位置相对于文件首的偏移字节数)
rewind(fp);//将文件内部的指针重新指向一个流的开头
//fclose(fp);
char *pData= new char[lsize+1];
memset(pData,0,lsize+1);//将内存空间都赋值为‘\0’
int result=fread(pData,1,lsize,fp);//将pfile中内容读入pread指向内存中
fclose(fp);
strData = std::string(pData);
if(pData)
{
delete[] pData;
pData = NULL;
}
return strData;
}
/*
作用: 根据要修改的参数列表, 修改从文件中读出来的string 字符串,并返回修改后的内容
*/
string ChangeYamlFile(string& strData,map<string,double>& modifyParamList)
{
string strLine="";
std::string oneLine="";
// 以\n 分行
std::vector<std::string> strList = StringSplit2(strData, "\n");
map<string,double>::iterator map_it;
//搜索每一行
for(int i=0;i<strList.size();i++)
{
oneLine = strList[i];
//去掉每行末尾的"\r"换行符号
oneLine = replace_all_distinct(oneLine,"\r", "");
//如果一行的第一个字符是'#',直接跳过
if(oneLine[0] == '#')
{
strLine +=oneLine + "\r\n";
}
else
{
string strSN1="";
double value=0.0;
//在一行中,搜索是否是需要修改的参数,如果是就修改,
for(map_it=modifyParamList.begin();map_it !=modifyParamList.end();map_it++)
{
cout<<map_it->first<<": "<<map_it->second<<endl;
strSN1=map_it->first;
value=map_it->second;
if(oneLine.size() >= strSN1.size() && oneLine.find(strSN1) != std::string::npos)
{
strLine += strSN1 + string(": ")+ to_string(value) + "\r\n";
break;
}
}
//搜索完,都没法匹配到,表明这一行不需要修改
if(map_it ==modifyParamList.end())
{
strLine +=oneLine + "\r\n";
}
}
}
strList.clear();
return strLine;
}
int writeToYamlFile(string& filePath,string& strData)
{
const char * p8File = (char*)filePath.c_str();
const char* pChangeData = strData.c_str();
//把修改后的内容写到新的文件中
int fd = open(p8File, O_CREAT | O_WRONLY | O_TRUNC,0644);
if(fd<0)
{
// LOGI("%s: vWriteDataToFile Create error",TAG);
cout<<"in writeToYamlFile open file error"<<endl;
return false;
}
int ret = write(fd, pChangeData, strData.size());
close(fd);
return ret;
}
void ChangeYaml(string& filePath,map<string,double> &modifyParamList)
{
string strData=ReadYamlFile(filePath);
string changeFile=ChangeYamlFile(strData,modifyParamList);
int ret=writeToYamlFile(filePath,changeFile);
if(!ret)
{
cout<<"cannot write to file ,open file error"<<endl;
}
}
int main()
{
string file="/home/feibot/c-project/yamlTest/visual_grab.yaml";
//string result=strReadYaml(file);
map<string,double> modifyParamList;
modifyParamList["cameral_distance_x"]=0.4;
modifyParamList["cameral_distance_y"]=0.5;
modifyParamList["release_num"]=21;
ChangeYaml(file,modifyParamList);
return 0;
}