How to print argv arguments from main function in C?
Is
argv
an array of characters? or is it an array of pointers pointing to characters?
argv
is a pointer to pointer to char
. When a list of arguments are passed through command line then an array of char
pointers are created and each of these pointers points to each of these arguments, stored in the form of strings, along with the program name. argv
points to the first pointer of this char *
array. Therefore, argv[i]
is a pointer to char
.
+--------------------------+
+----+ +--> | argument 1 (program name)|
argv[0]+----> | | | +--------------------------+
| +----+
+----| +--------------------------+
| +-------> | argument 2 |
| | +--------------------------+
+----+
| +----+ +--------------------------+
| | +--> | argument 3 |
+----+ +--------------------------+
"char *" array
You need to change
printf("%s",*argv[i]);
to
printf("%s",argv[i]);
*argv[i]
is of type char
. %s
expects a type of char *
.
Let's explain out things step by step. First of all, when you invoke your program by calling something like...
./my-program arg0 arg1 arg2
You're passing it a series of three arguments, right? And each argument is a string, right? Now, the main
function, can have one of two prototypes, as specified by the C standard...
int main(); // Let's not worry about this for now
int main(int argc, char **argv);
The idea is that main
is able to handle the arguments that you provided. argc
provides the number of arguments. If you noticed, while passing three arguments, argc
is 4! This happens because a first argument is passed before all others, ./my-program
, and lets your program recognize itself.
Now, what does char **argv
mean? Something of the form X*
is a pointer to X
, right? So, char *
is a pointer to char
, and char **
is a pointer to pointer to char
. In C, a string is simply a zero-terminated array of char
, and an array can be "degraded" into a pointer. This means that argv
is an array of strings, the first of which, argv[0]
, is the program's name.
Now, the C standard allows you to write any "compatible" prototype for main
. For instance, you can write any of these...
int main(int argc, const char *const argv[]);
int main(int argc, const char *argv[])
int main(int argc, const char **argv);
int main(int argc, const char *const *const argv);
You don't need to understand what they all mean now, just that argv
is an array of strings, and that you should never modify strings as the original main
prototype appears to trust you onto. Now, knowing that arguments start at argv[1]
, your code...
for(i=0;i<argc-1;i++)
Means: "For each i
in the range of 0 through argc - 1
".
printf("%s",*argv[i]);
Means: "Print the first character of the i
th element of argv
". Why would this be wrong? First of all, you're printing a char
, and telling printf
that it is a string. This has undefined behavior. Then, you're iterating over the first i
th elements of argv
. This means that the first, "non-argument" element will be included in the mix, and the last argument won't be. To solve it, write somethinge like...
for(i = 1; i < argc; i++)
Means: "For each i
in the range from 1
up to argc
".
printf("%s", argv[i]);
Means: "Print the i
th element of argv
onto stdout
.
char *argv[]
is pointer to pointer to char
because arrays in function arguments are automatically converted to pointer pointing at elements of the array.
You invoked undefined behavior by passing data having wrong type to printf()
: %s
expects char*
, but you passed char
(converted to int
for variable number arguments).
Remove the extra *
o dereference the pointer.
#include<stdio.h>
int main(int argc, char *argv[])
{
int i;
printf("%d\n",argc);
for(i=0;i<argc-1;i++)
{
printf("%s",argv[i]);
}
return 0;
}
Also you may want i<argc
instead of i<argc-1
. Why not print the last argument?