gpt4 book ai didi

c++ - 在 Windows 中使用 boost::program_options 从命令行参数读取 Unicode 字符

转载 作者:行者123 更新时间:2023-11-30 04:41:19 25 4
gpt4 key购买 nike

我有几个从命令行参数读取文件路径的 Windows 应用程序。一切都完美无缺,除了传递带有非 ANSI 字符的路径时。我预料到了这一点,但不知道如何处理。可能是入门级问题,但这让我发疯。

我当前的代码如下:

int main(int argc, char* argv[]) {
namespace po = boost::program_options;

po::options_description po_desc("Allowed options");
po_desc.add_options()
("file", po::value<std::string>(), "path to file");

po::variables_map po_vm;
try {
po::store(po::parse_command_line(argc, argv, po_desc), po_vm);
po::notify(po_vm);
} catch (...) {
std::cout << po_desc << std::endl;
return false;
}

const std::string file_path = po_vm["file"].as<std::string>();

// ...
}

我发现如果我将 file_path 的类型从 std::string 替换为 boost::filesystem::path,现在读取了一些路径。我不知道确切原因,但可以推断它必须与 Latin1 字符集的翻译。

例如,有以下文件:

malaga.txt
málaga.txt
mąlaga.txt

第一个总是被正确读取,而第二个在使用 std::string file_path 而不是 boost::filesystem::path file_path 时失败。第三个总是失败。

我尝试将主函数切换为 int main(int argc, wchar_t* argv) 并使用 std::wstring 作为参数类型,但它是与 boost::program_options 解析器不兼容。

如何正确读取此类 Unicode 文件名?

最佳答案

感谢大家发表评论,感谢他们,我设法解决了我的问题。

长话短说

这里是固定代码:

int wmain(int argc, wchar_t* argv[]) { // <<<
namespace po = boost::program_options;

po::options_description po_desc("Allowed options");
po_desc.add_options()
("file", po::wvalue<std::wstring>(), "path to file") // <<<
("ansi", po::value<std::string>(), "an ANSI string")
;

po::variables_map po_vm;
try {
po::store(po::wcommand_line_parser(argc, argv) // <<<
.options(po_desc)
.run(),
po_vm);
po::notify(po_vm);
} catch (...) {
std::cout << po_desc << std::endl;
return false;
}

const boost::filesystem::path file_path = po_vm["file"].as<std::wstring>(); // <<<

// ...
}

说明

首先,切换到wmainwchar_t* argv:如@erik-sun 所述, 有必要将入口点切换到 Unicode 感知函数。重要说明:可以使用 int main(int, wchar_t*) (在某种意义上它会编译)但它不会接收具有正确编码的参数并且解析器将失败,你必须使用 wmain

然后,Unicode support link@richard-critten 提供对于理解编译错误非常有用:

  • 当类型为宽字符时使用boost::program_options::wvalue。内部实现使用字符串流:默认的仅适用于 8 位字符。
  • 使用boost::program_options::wcommand_line_parser 接受wchar_t* 参数。不幸的是,此类没有一体化构造函数,您必须使用long 形式来解析命令行。
  • 最后,在需要时将值检索为 std::wstring

我扩展了代码片段以表明它仍然与 std::string 输入兼容。

旁注

我的完整解决方案需要在某个时候实例化 Qt QApplicationQApplication 构造函数与宽字符 argv 不兼容。由于 Qt 部分不需要命令行交互(一切都在很久之前由 Boost 处理),它可以被重写以接收假参数:

int fake_argc = 1;
char* fake_argv[] = {"AplicationName"};
QApplication a(fake_argc, fake_argv);

关于c++ - 在 Windows 中使用 boost::program_options 从命令行参数读取 Unicode 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59143297/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com