【发布时间】:2013-01-17 23:26:45
【问题描述】:
*强调文本*如何使用 Boost 程序选项从命令行接受单字节变量?
--id1=1 --id2=1 的命令行参数导致 id1=49(或 '1', 0x31)和 id2=1 的值。
#include <stdint.h>
#include <iostream>
#include <boost/program_options.hpp>
using namespace std;
int main(int argc, char** argv)
{
(void)argc;
(void)argv;
namespace po = boost::program_options;
const int myargc = 3;
const char* myargv[] = {"foo","--id1=1","--id2=2" };
uint8_t id1;
uint16_t id2; // works as expected.
po::variables_map vm;
po::options_description cmd_options( "Command options" );
cmd_options.add_options()
( "id1", po::value<uint8_t >( &id1 )->default_value( 0 ), "A 1-byte ID" )
( "id2", po::value<uint16_t>( &id2 )->default_value( 0 ), "A 2-byte ID" )
;
po::store( po::parse_command_line( myargc, myargv, cmd_options ), vm );
po::notify( vm );
// Using command line parameters of --id1=1 --id2=1,
// at this point, id1=49 (or '1', 0x31) and id2=1.
cout << "BPO parsing of " << myargv[1] << " and " << myargv[2] << endl;
cout << "id1: " << id1 << endl;
cout << "id1: " << (int)id1 << endl;
cout << "id2: " << id2 << endl;
id1 = boost::lexical_cast<uint8_t>("1");
id2 = boost::lexical_cast<int>("2");
cout << "Using boost::lexical_cast" << endl;
cout << "id1: " << id1 << endl;
cout << "id1: " << (int)id1 << endl;
cout << "id2: " << id2 << endl;
}
输出是:
BPO parsing of --id1=1 and --id2=2
id1: 1
id1: 49
id2: 2
Using boost::lexical_cast
id1: 1
id1: 49
id2: 2
Boost 最终调用 boost::lexical_cast("1")' 转换为字符而不是数值 - “1”变成了 '1',即 49。
有没有办法改变 boost::program_options::add_options() 初始化以将单字节值视为整数而不是字符串/字符?如果不是,我有哪些选项可以更改解析或映射?明显(但不利)的选项是:[1] 不要使用类似 char 的值 [2] 手动解析(绕过 Boost)或 [3] 在 Boost 解析后执行二次转换。
【问题讨论】:
-
哪个平台和工具链?
-
我在 VC2012 的 Win7-64 上发现了这个,但这也适用于 Linux X86 和 Linux ARM 和 gcc。我认为这并不重要 - 这不是特定于平台的错误,而是流式传输的工作方式,并且任何解决方案都可以跨平台工作。
-
I tried your reproducer 并查看预期结果。我在 ppc64 Linux 和 Mac OS X 上看到了相同的行为。也许您可以详细说明您的环境?
-
山姆:谢谢。您的代码重现了该问题,我使用您的代码示例编辑了我的帖子,并添加了强制转换以使问题更加明显。我在 Windows 和 Linux x86 上得到了相同的结果,这是由 boost::lexical_cast 引起的。顺便说一句,感谢有关 LiveWorkSpace 的提示。
-
我猜这是因为
uint8_t可能是char 的typedef。也许将此作为错误提交?
标签: c++ boost boost-program-options