17

I'm writing Win32 console application, which can be started with optional arguments like this:

app.exe /argName1:"argValue" /argName2:"argValue"

Do I have to parse it manually (to be able to determine, which arguments are present) from argc/argv variables, or does Win32 API contain some arguments parser?

LihO
  • 41,190
  • 11
  • 99
  • 167
tomas
  • 669
  • 2
  • 11
  • 23
  • 1
    http://note.sonots.com/Comp/CompLang/cpp/getopt.html – Prof. Falken Oct 02 '12 at 11:22
  • See the documentation of [WinMain](http://msdn.microsoft.com/en-us/library/windows/desktop/ff381406%28v=vs.85%29.aspx), the command line parameters come as a single string and not as argv/argc (though you can get it in that format through another function). – Lundin Oct 02 '12 at 11:23

9 Answers9

16

There is no Win32 support for parsing command-line arguments.

See related articles at MSDN:
Parsing C++ Command-Line Arguments
Argument Definitions
Customizing C++ Command-Line Processing

also look at similar questions:
What parameter parser libraries are there for C++?
Parsing parameters to main()
Option Parsers for C/C++?
What's an effective way to parse command line parameters in C++?
...

Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167
9

The only support that Win32 provides for command line arguments are the functions GetCommandLine and CommandLineToArgvW. This is exactly the same as the argv parameter that you have for a console application.

You will have to do the parsing yourself. Regex would be a good option for this.

Superman
  • 3,027
  • 1
  • 15
  • 10
7

You could mess around with various libraries and stuff... But sometimes all you require is something simple, practical and quick:

int i;
char *key, *value;

for( i = 1; i <= argc; i++ ) {
    if( *argv[i] == '/' ) {
        key = argv[i] + 1;
        value = strchr(key, ':');
        if( value != NULL ) *value++ = 0;
        process_option( key, value );
    } else {
        process_value( argv[i] );
    }
}

You get the idea...

This is assuming a normal Win32 console app as you have implied (which has a traditional main function). For Win32 apps you come in at WinMain instead, as another person has already commented.

paddy
  • 60,864
  • 6
  • 61
  • 103
  • 2
    When using the CRT that ships with Visual Studio, you have access to the command line arguments through the [__argc, __argv, __wargv](https://learn.microsoft.com/en-us/cpp/c-runtime-library/argc-argv-wargv) symbols. They are populated for applications that run in the WINDOWS subsystem as well. Alternatively use the Windows API call [CommandLineToArgvW](https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391.aspx) to parse the return value of [GetCommandLineW](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156.aspx). – IInspectable Oct 10 '17 at 07:32
3

Just for the record, if you use MinGW's GCC, rather than Microsoft's MSVC, you get GNU getopt, (which also includes getopt_long and getopt_long_only variants), included within the standard runtime library.

Keith Marshall
  • 1,980
  • 15
  • 19
3

You can parse the arguments by using GetCommandLine, PathRemoveArgs, PathGetArgs in a loop

https://msdn.microsoft.com/en-us/library/windows/desktop/bb773742(v=vs.85).aspx

  • 1
    Brittle, at best. From the [documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/bb773742.aspx): *"This function should not be used on generic command path templates (from users or the registry), but rather it should be used only on templates that the application knows to be well formed."* It's easier and safer to use [CommandLineToArgvW](https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391.aspx) instead. – IInspectable Oct 10 '17 at 07:28
3

I have been developing and using libparamset that is written in plain C. It is really powerful and works well on Windows. It provides:

  • Is cross-platform.
  • Wildcard support for file input on Windows!
  • Powerful features. See libparamset.
Taavi Valjaots
  • 111
  • 1
  • 4
2

If your needs are simple, you might want to take a look at Argh!.
It is single header and super easy to use:

int main(int, char* argv[])
{
    argh::parser cmdl(argv);          // declare

    if (cmdl[{ "-v", "--verbose" }])  // use immediately
        std::cout << "Verbose, I am.\n";

    return EXIT_SUCCESS;
}

By being unintrusive, it doesn't take over you main() function.

From the Readme:

Philosophy

Contrary to many alternatives, argh takes a minimalist laissez-faire approach, very suitable for fuss-less prototyping with the following rules:

The API is:

  • Minimalistic but expressive:
    • No getters nor binders
    • Just the [] and () operators.
    • Easy iteration (range-for too).
  • You don't pay for what you don't use;
  • Conversion to typed variables happens (via std::istream >>) on the user side after the parsing phase;
  • No exceptions thrown for failures.
  • Liberal BSD license;
  • Single header file;
  • No non-std dependencies.

argh does not care about:

  • How many '-' preceded your option;
  • Which flags and options you support - that is your responsibility;
  • Syntax validation: any command line is a valid (not necessarily unique) combination of positional parameters, flags and options;
  • Automatically producing a usage message.
Adi Shavit
  • 16,743
  • 5
  • 67
  • 137
1

I don't believe that there is a Win32 API available. You can look for a Windows implementation of getopt or another library.

kgiannakakis
  • 103,016
  • 27
  • 158
  • 194
1

Not sure about existence of such a win32 api function(s), but Boost.Program_Options library could help you.

usta
  • 6,699
  • 3
  • 22
  • 39