I have this code in boost::program options:
("output_path,o", po::value< std::string >(&outputPath)->implicit_value(""), "path to where the output should be created.")
and on command line I have:
-o "C:\My Data\ImagesWithDifferentResolution\"
when boost options fill outputPath with data, I am getting this value in the variable:
C:\My Data\ImagesWithDifferentResolution"
note the extra quote at the end of path.
How can I fix it?
To be clear it is a bug in boost. I know that I should escape the strings when I am compiling my code, but this is the way that boost program options works and extracting input data from command line.
So to explain a bit more:
My program called testPrg.exe and I am trying to call it in the following way:
testprg.exe -o "C:\My Data\ImagesWithDifferentResolution\"
which is correct and my user should be able to do this. There is no need to escape the \ on command line.
But the boost program options, mistakenly convert the last \" into a escape value.
test application which shows the bug:
main()
{
po::options_description desc("Allowed options");
std::string outputPath;
desc.add_options()
("output_path,o", po::value< std::string >(&outputPath)->implicit_value(""), "path to where the output should be created.")
;
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
po::notify(vm);
std::cout<<outputPath <<std::endl;
}
compile the cod with boost 1.58 and run it as explained above and inspect the output.
This is not a bug in Boost.Program_options; it is the expected behavior of the Microsoft C/C++ startup code provided by your compiler. That is, the \"
has already been converted to "
by the time it is passed to main
in argv
.
From Parsing C Command-Line Arguments in the Visual Studio 2015 reference:
A double quotation mark preceded by a backslash,
\"
, is interpreted as a literal double quotation mark ("
).Command-Line Input | argv[1] | argv[2] | argv[3] -------------------+---------+---------+--------- "ab\"c" "\\" d | ab"c | \ | d
A possible workaround might be to call GetCommandLine
to get lpCommandLine
and pass that to split_winmain
(though that might have the same behavior as the Microsoft startup code) or split the command line yourself.