C++ 如何使用yaml cpp修改值?
我正在尝试为我的应用程序创建配置文件,为此我使用C++ 如何使用yaml cpp修改值?,c++,yaml,yaml-cpp,C++,Yaml,Yaml Cpp,我正在尝试为我的应用程序创建配置文件,为此我使用yaml-cpp库生成配置,并在用户更改应用程序中的某些设置或内容时进行修改。我为此设置了一个单独的类,构造函数生成yaml文件,如下所示 Serializer::Serializer(const std::string& filepath) { std::ifstream ifin(filepath); if (!ifin) { emitter << YAML::Comment(&qu
yaml-cpp
库生成配置,并在用户更改应用程序中的某些设置或内容时进行修改。我为此设置了一个单独的类,构造函数生成yaml
文件,如下所示
Serializer::Serializer(const std::string& filepath)
{
std::ifstream ifin(filepath);
if (!ifin)
{
emitter << YAML::Comment("Hello");
emitter << YAML::BeginDoc;
emitter << "This is the configuration file for the Sample Browser,"
<< YAML::Newline;
emitter << "feel free to edit this file as needed";
emitter << YAML::EndDoc;
emitter << YAML::BeginMap;
emitter << YAML::Newline << YAML::Key << "Window";
emitter << YAML::BeginMap;
emitter << YAML::Key << "SizeW" << YAML::Value << "1280";
emitter << YAML::Key << "SizeH" << YAML::Value << "720";
emitter << YAML::EndMap << YAML::Newline;
emitter << YAML::Newline << YAML::Key << "Media";
emitter << YAML::BeginMap;
emitter << YAML::Key << "Autoplay" << YAML::Value << "false";
emitter << YAML::Key << "Loop" << YAML::Value << "false";
emitter << YAML::Key << "Muted" << YAML::Value << "false";
emitter << YAML::EndMap << YAML::Newline;
emitter << YAML::Newline << YAML::Key << "Display";
emitter << YAML::BeginMap;
emitter << YAML::Key << "Font";
emitter << YAML::BeginMap;
emitter << YAML::Key << "Family" << YAML::Value << "Sans";
emitter << YAML::Key << "Size" << YAML::Value << "10";
emitter << YAML::EndMap;
emitter << YAML::EndMap << YAML::Newline;
emitter << YAML::Newline << YAML::Key << "Import_dir";
emitter << YAML::BeginMap;
emitter << YAML::Key << "AutoImport" << YAML::Value << "false";
emitter << YAML::Key << "Directory" << YAML::Value << "/home/apoorv";
emitter << YAML::EndMap << YAML::Newline;
emitter << YAML::EndMap;
std::ofstream ofout(filepath);
ofout << emitter.c_str();
}
else
{
wxLogDebug("Config file already exists! Skipping..");
}
}
我希望当用户更改字体时,相关的键值也会随所选选项而更改。我试着做一个函数,应该这样做
void Serializer::SerializeDisplaySettings(const std::string& filepath, wxFont& font)
{
YAML::Emitter out;
std::string fontFace = font.GetFaceName().ToStdString();
int fontSize = font.GetPointSize();
std::ifstream ifin(filepath);
try
{
YAML::Node config = YAML::LoadAllFromFile(filepath)[1];
auto display = config["Display"];
if (auto fontSetting = display["Font"])
{
wxLogDebug("Changing font settings");
wxLogDebug("Font face: %s", fontFace);
wxLogDebug("Font size: %d", fontSize);
out << YAML::Key << fontSetting["Family"] << YAML::Value << fontFace;
out << YAML::Key << fontSetting["Size"] << YAML::Value << fontSize;
std::ofstream ofout(filepath);
ofout << out.c_str();
}
else
{
wxLogDebug("Error! Cannot fetch values.");
}
}
catch(const YAML::ParserException& ex)
{
std::cout << ex.what() << std::endl;
}
}
void Serializer::SerializeDisplaySettings(const std::string和filepath,wxFont和font)
{
YAML::发射极输出;
std::string fontFace=font.GetFaceName().ToStdString();
int fontSize=font.GetPointSize();
std::ifstream-ifin(文件路径);
尝试
{
YAML::Node config=YAML::LoadAllFromFile(文件路径)[1];
自动显示=配置[“显示”];
如果(自动字体设置=显示[“字体”])
{
wxLogDebug(“更改字体设置”);
wxLogDebug(“字体面:%s”,字体面);
wxLogDebug(“字体大小:%d”,字体大小);
out覆盖该文件,当然它只包含您提供给发射器的项目。如果要修改加载的文件,应更新config
中的值,并将其全部写回:
fontSetting[“Family”]=fontFace;
fontSetting[“大小”]=fontSize;
谢谢,这是可行的,但它也删除了我的注释和YAML
Doc。@apoorv569添加了代码以保留其他文档。我很感激您提供的代码。它解决了问题,但也弄乱了我的间距和新行,在原始帖子中,您会看到所有父节点之后都有新行,即窗口
之前Media
、Display
和Import\u Dir
。我必须手动编辑文件吗?编辑时,它会再次添加这些新行。因为当我向文件中添加更多项目时,每次编辑该文件时,添加回这些注释和所有内容会变得非常繁琐。@apoorv569加载和编辑时,您无法保留所有格式有关YAML文件的详细信息,请参阅。这不是YAML的工作方式。正如您在中所看到的,解析器不为注释、非内容换行符等提供事件,因此它们无法恢复地丢失。@APORV569 XML被指定为在加载时保留所有内容,如果这正是您所追求的。当然,许多开发人员支持JSON是有原因的/YAML/TOML等。这些语言是为用户友好而编写的,其中包括使用空白进行格式化,而这种格式化被解析器忽略,这也是无法准确复制加载的文件的主要原因。
void Serializer::SerializeDisplaySettings(const std::string& filepath, wxFont& font)
{
YAML::Emitter out;
std::string fontFace = font.GetFaceName().ToStdString();
int fontSize = font.GetPointSize();
std::ifstream ifin(filepath);
try
{
YAML::Node config = YAML::LoadAllFromFile(filepath)[1];
auto display = config["Display"];
if (auto fontSetting = display["Font"])
{
wxLogDebug("Changing font settings");
wxLogDebug("Font face: %s", fontFace);
wxLogDebug("Font size: %d", fontSize);
out << YAML::Key << fontSetting["Family"] << YAML::Value << fontFace;
out << YAML::Key << fontSetting["Size"] << YAML::Value << fontSize;
std::ofstream ofout(filepath);
ofout << out.c_str();
}
else
{
wxLogDebug("Error! Cannot fetch values.");
}
}
catch(const YAML::ParserException& ex)
{
std::cout << ex.what() << std::endl;
}
}