【问题标题】:Boost library, using std::wstring as filename with boost::property_tree::read_xmlBoost 库,使用 std::wstring 作为文件名和 boost::property_tree::read_xml
【发布时间】:2014-10-23 22:19:07
【问题描述】:

我最近开始使用 std::wstring 而不是 std::string 来避免非 ASCII 字符的奇怪结果,并且我没有找到一种方法来读取路径类型为 std::wstring 的 XML 文件使用 boost图书馆。

我现在很安静地使用boost 库。

我将boost::property_tree::read_xml 函数与boost::property_tree::wptree 一起使用,而不是通常的ptree 结构。但遗憾的是,我无法将std::wstring 作为 read_xml 的第一个参数,这使得这一切变得更加困难。

我的问题是,对于读取路径存储为std::wstring 的 XML 文件是否有任何解决方法?

提前致谢!

【问题讨论】:

    标签: c++ xml boost wstring widestring


    【解决方案1】:

    您可以使用支持来自 Boost Filesystem 的 wpath 的 Boost Iostreams file_descriptor_sink 设备:

    #include <boost/property_tree/xml_parser.hpp>
    #include <boost/iostreams/device/file_descriptor.hpp>
    #include <boost/iostreams/stream.hpp>
    #include <boost/filesystem.hpp>
    #include <iostream>
    
    namespace pt = boost::property_tree;
    namespace io = boost::iostreams;
    namespace fs = boost::filesystem;
    
    int main()
    {
        fs::wpath const fname = L"test.xml";
        io::file_descriptor_source fs(fname);
        io::stream<io::file_descriptor_source> fsstream(fs);
    
        pt::ptree xml;
        pt::read_xml(fsstream, xml);
    
        for (auto const& node : xml.get_child("root"))
            std::cout << node.first << ": " << node.second.get_value<std::string>() << "\n";
    }
    

    查看 Live On Coliru 它使用输入文件的位置:

    <root>
        <child nodetype="element" with="attributes">monkey show</child>
        <child nodetype="element">monkey do</child>
    </root>
    

    并打印:

    child: monkey show
    child: monkey do
    

    【讨论】:

    • 如果我的文件名或路径包含非 ascii 字符,这是否有效?
    • @ashishg 我没有对此进行测试,但我认为boost::filesystem::path::codecvt() 执行了相关转换,所以:是的
    • coliru.stacked-crooked.com/a/7007dd21b1c12f14 我尝试修改您的示例以包含非 ascii,但它出错了。
    • @ashishg 为我工作。 Anyhoops,灌输特定的语言环境 *does the job on Coliru
    【解决方案2】:

    我找到了一个相当简单的可行解决方案,我所做的只是使用std::wifstream 作为boost::property_tree::read_xml 方法的第一个参数。

    基本上三行代码:

    boost::property_tree::wptree pt;
    std::wifstream f(L"C:/äöå/file.xml");
    boost::property_tree::read_xml(f, pt);
    

    【讨论】:

    • 这不是可移植的:en.cppreference.com/w/cpp/io/basic_ifstream/basic_ifstream - 这也是 boost::iostreams::file_source doesn't support wide string filenames 的原因(因为它依赖于 std::fstream) - 提升问题 #3088由于这个原因,被标记为“WontFix”。
    • @sehe 好的,但它确实适用于 Microsoft Windows?因为我的应用程序(还)不是跨平台的。无论如何,谢谢你的信息和答案。
    • 干杯。我认为它只适用于 MSVC 的标准库实现。 (它仍然不能与 Windows 上的 MingW、GCC、Clang 或 Intel C++ 编译器一起使用)。这不是 MSVC 具有非标准的第一件事。一般来说,wstring 很少在 Windows 之外使用,因为只有在 MSVC 上 wstring 才具有 16 位字符类型,而这恰好与 UTF16 的 Windows“首选”字符编码相吻合
    • @sehe 我明白了,如果在 Windows 和 Visual Studio 中开发,使用您的方法会有什么好处吗? Vcredist 将安装在所有运行我的程序的计算机上。
    • 我打赌没有。如果您希望支持这一切,您可以使用 MSVC 扩展。 (docs)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 2017-12-27
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多