I just wrote a small program that reads command line arguments in C, nothing too difficult. I was also modifying them, for example changing the first character of the parameter to uppercase.
I know that you shouldn't modify string literals as it can cause undefined behavior, so was just wondering if the strings in the *argv[]
are literals that you shouldn't change.
int main(int argc, char *argv[])
From the C11 standard draft N1570, §5.1.2.2.1/2:
The parameters argc
and argv
and the strings pointed to by the argv
array shall be modifiable by the program, and retain their last-stored
values between program startup and program termination.
They are modifiable. That means they are not string literals.
But be careful: the upper citation only refers to pointers to strings, excluding the obligatory null pointer at argv[argc]
1.
From the C11 standard draft N1570, §5.1.2.2.1/2 (same as above)1:
argv[argc]
shall be a null pointer
Notes:
Something regarding this sentence:
I know that you shouldn't modify string literals as it can cause
undefined behavior [...]
"can"? It does always. Undefined behavior includes expected, as if well-defined, and unexpected behavior.
1 Thanks to @black!
The arrays that support the strings in argv
are modifiable.
But you have no way to know their sizes.
I would frown upon seeing code that (tries to) increase the size of the strings.
#include <stdio.h>
#include <string.h>
// this program may behave erraticaly
int main(int argc, char **argv) {
for (int k = 1; k < argc; k++) {
printf("original argv[%d] is %s\n", k, argv[k]);
}
printf("\n");
for (int k = 1; k < argc; k++) {
strcat(argv[k], " foo"); // add foo to each argv string
printf("first modification to argv[%d] is %s\n", k, argv[k]);
}
printf("\n");
for (int k = argc; k > 1; k--) {
strcat(argv[k - 1], " bar"); // add bar to each argv string
printf("final argv[%d] is %s\n", k - 1, argv[k - 1]);
}
return 0;
}
On my machine, calling that program with one two three
arguments produces
original argv[1] is one
original argv[2] is two
original argv[3] is three
first modification to argv[1] is one foo
first modification to argv[2] is foo foo
first modification to argv[3] is foo foo
final argv[3] is foo foo bar
final argv[2] is foo foo foo bar bar
final argv[1] is one foo foo foo bar bar bar