Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are the strings in argv modifiable?

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[]) 
like image 217
ash.KETCHUP Avatar asked Jan 30 '16 14:01

ash.KETCHUP


People also ask

Are strings in argv null terminated?

Yes. The non-null pointers in the argv array point to C strings, which are by definition null terminated.

Are argv strings?

The argv parameter is an array of pointers to string that contains the parameters entered when the program was invoked at the UNIX command line.

Is argv a string or a char?

The first (conventionally called argc) is the number of command-line arguments the program was invoked with; the second (argv) is a pointer to an array of character strings that contain the arguments, one per string.

Are command line arguments stored as strings?

The command-line arguments are passed to the program at run-time. Passing command-line arguments in a Java program is quite easy. They are stored as strings in the String array passed to the args parameter of main() method in Java.


2 Answers

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!

like image 64
cadaniluk Avatar answered Oct 13 '22 23:10

cadaniluk


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 
like image 44
pmg Avatar answered Oct 13 '22 22:10

pmg