Search code examples
c++boostboost-program-options

boost program options changes data when it reads from command line (is it a bug in boost?)


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?

EDIT 1

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.


Solution

  • 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.