Copying Command Line Arguments Into an Array
Solution 1
You're not allocating or copying the terminating NULL characters:
This line needs to be changed to this for the NULL.
array[i] = malloc((strlen(*(argv + i)) + 1) * sizeof(char));
And the loop should be changed to this:
for(j = 0; j <= strlen(*(argv + i)); j++){
Also, the code can be better optimized if you saved the result of the strlen()
call since you call it in so many places.
Try the loop as this:
// For each element allocate the amount of space for the number of chars in each argument
for(i = 0; i < argc; i++){
int length = strlen(argv[i]);
array[i] = malloc((length + 1) * sizeof(char));
int j;
// Cycle through all the chars and copy them in one by one
for(j = 0; j <= length; j++){
array[i][j] = argv[i][j];
}
}
Solution 2
first you need to allocate a vector of char*, not just a char*
char **array;
array = malloc(sizeof(char*)*(argc+1)); // plus one extra which will mark the end of the array
now you have an array[0..argc]
of char*
pointers
then for each argument you need to allocate space for the string
int index;
for (index = 0; index < argc; ++index)
{
arrray[index] = malloc( strlen(*argv)+1 ); // add one for the \0
strcpy(array[index], *argv);
++argv;
}
array[index] = NULL; /* end of array so later you can do while (array[i++]!=NULL) {...} */
Matt
Updated on June 04, 2022Comments
-
Matt almost 2 years
For a program, I would like to make an array copy of the arguments sent in by command line using malloc().
So for example if I do ./a.out one two three I want an array with {a.out, one, two, three} in it.
However, I have some issues getting my program to work. Here's what I have:
static char** duplicateArgv(int argc, char **argv) { char *array; int j = 0; // First allocate overall array with each element of char* array = malloc(sizeof(char*) * argc); int i; // For each element allocate the amount of space for the number of chars in each argument for(i = 1; i < (argc + 1); i++){ array[i] = malloc(strlen(*(argv + i)) * sizeof(char)); int j; // Cycle through all the chars and copy them in one by one for(j = 0; j < strlen(*(argv + i)); j++){ array[i][j] = *(argv + i)[j]; } } return array; }
As you might imagine, this doesn't work. I apologize ahead of time if this somehow totally doesn't make sense, as I just started learning about pointers. Also, I'm not quite sure how to write code to free up every element in the *array after I do what I need to the copy.
Could anyone give me some tips on what I should look into to make it do what I want?
Thanks for any help!
-
Matt over 12 yearsI tried to print it with while(*array){printf("%s", *array++);}, but I don't get any output (I get a seg fault). Hmm...
-
Mysticial over 12 yearsYou also need to change
char *array;
tochar **array;
Is it still not working? -
Mysticial over 12 yearsI overlooked one more thing: Your loop indexing should start from 0 and not 1. I've edited it into the answer.
-
Matt over 12 yearsI changed it and this works. Thank you so much! However, I am wondering why you used argv[i][j] and strlen(argv[i]) rather than strlen(*(argv +i))? I thought the expressions were equivalent.
-
Mysticial over 12 yearsI made that change because I wasn't sure of the precedence between * and []. Then I just copied and pasted it wherever I found it.
-
Matt over 12 yearsEDITED: Nevermind I see what you're saying. Thanks again for all your help!
-
Mysticial over 12 yearsYou had
*(argv + i)[j]
. I wasn't sure if it would be parsed as(*(argv + i))[j]
or*((argv + i)[j])
. And it makes a difference in this case. -
Matt over 12 years