boost program option 库处理中文命令行

来源:互联网 发布:电话吸费软件 编辑:程序博客网 时间:2024/06/05 13:54

 

boost 的 program option 为处理复杂的命令行提供方便。

若用 VS2005 以上版本来编译程序,则当程序处理包含中文的命令行是将可能抛

“charactor conversion fail” 的异常。

现将测试后的经验总结如下:

 

先看一段代码:

 

#include "stdafx.h"#include <boost/program_options/option.hpp>#include <boost/program_options/options_description.hpp> #include <boost/program_options/variables_map.hpp>#include <boost/program_options/cmdline.hpp>#include <boost/program_options/parsers.hpp> #include <iostream>#include <string>namespace po = boost::program_options;using namespace std;int _tmain(int argc, _TCHAR* argv[]){std::locale::global(std::locale(""));try {string inName, outName;float val;po::options_description desc("Allowed options");desc.add_options()("help,h", "produce help message")("if,i", po::value< string >(), "input file")("of,o", po::value< string >(), "output file")("float,f", po::value< float >( &val )->default_value(90), "a float number");po::variables_map vm;po::store(po::parse_command_line(argc, argv, desc), vm);po::notify(vm); if ( argc<2 || vm.count("help")) {cout << desc << "\n";return 1;}if (vm.count("if")) {inName = vm["if"].as<string>();cout << "input file is : "  << inName << endl;}if (vm.count("of")) {outName = vm["of"].as<string>();cout << "output file is : "  << outName << endl;}DoSomething( inName, outName, val);} catch (exception &e) {cout << e.what() << endl;}}

 

1.  std::locale::global(std::locale("")); 非常重要。它保证了使用操作系统当前的字符集转换器,这使得程序内部可以正确的在  ANSI-UTF16-UTF8之间转换。否则 C++默认的字符集是西文,处理中文必然出错。

2. 无论VC编译选项中,字符集是“ANSI编码”还是“Unicode 编码” (这导致 argv 的类型分别为 char * 或者 wchar_t *),上述 program option的代码都不需要改变,就当做它总是处理 ANSI 命令行一样。之所以有这个特点是 因为po::parse_command_line 有处理 char * 和 wchar_t* 两个版本。因此无论 argv 的类型如何,po::parse_command_line 总是能够正确处理。对于 Unicode (wchar_t *), 将自动转换为 utf-8 保存到 po::variables_map 中,而提取的时候总是用vm["if"].as<string>获得ANSI编码的字符串。 

3. 事实上,将wchar_t *保存为 utf-8 是program option提供的处理Unicode的唯一途径。提取时只能用 vm["if"].as<string>, 而不能用 vm["if"].as<wstring>,  前者获得的是ANSI编码的字符串,而后者会抛异常 “boost::bad_any_cast: failed conversion using boost::any_cast”。

 

原创粉丝点击