Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用yaml cpp修改值?_C++_Yaml_Yaml Cpp - Fatal编程技术网

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;
    }
}