cmd.exe: Splitting command line into arguments when executing an exe
showArguments.c
The following simple c program makes it possible to analyse how a command line is parsed and which arguments are passed to an executable when invoked from cmd.exe:
//
// cl /nologo /FeshowArguments.exe showArguments.c
// cl /nologo /FeExpandArguments.exe showArguments.c /link setargv.obj
//
#include <stdio.h>
int main(int argc, char *argv[]) {
int i;
for (i=1; i<argc; i++) {
printf("argv[%2d] = %s\n", i, argv[i]);
}
}
Below, there are some findings from experimenting with this program.
Seperating arguments by white space
Fundamentally, the arguments are separated by white space (any consecutive combination of spaces or tabs):
showArguments.exe foo bar baz
argv[ 1] = foo
argv[ 2] = bar
argv[ 3] = baz
Including white space into arguments
By enclosing words into pairs of double quotes, the words including the white space become one argument:
showArguments.exe "this is one argument" "This is the 2nd argument" "The 3rd"
argv[ 1] = this is one argument
argv[ 2] = This is the 2nd argument
argv[ 3] = The 3rd
Escaping double quotes
A double quote is escaped with a backslash:
showArguments.exe \" "the 2nd arg" "An arg containing an \"." four
argv[ 1] = "
argv[ 2] = the 2nd arg
argv[ 3] = An arg containing an ".
argv[ 4] = four
Backslashes only escape double-quotes
Backslashes only escape double-quotes (and sometimes themselves). They have no special meaning when preceding other characters:
Special case: enclosing one word into double quotes
A special case seems to be if one word is enclosed into double quotes.
In this case, the double quotes are just skipped
showArguments.exe "arg One" "Did he say "hello"?" "arg three"
argv[ 1] = arg One
argv[ 2] = Did he say hello?
argv[ 3] = arg three
If "hello" is replaced with "hello world" in the preceding example, the output becomes as follows. It's not clear to me what rule is responsible for that:
showArguments.exe "arg One" "Did he say "hello world"?" "arg three"
argv[ 1] = arg One
argv[ 2] = Did he say hello
argv[ 3] = world?
argv[ 4] = arg three
Star and question mark
If not linked with setargv.obj, stars and questionmarks are not treated specially: