Reputation:
So I just learnt that we can give two arguments into main function namely "argc" and "argv. However I am not able to understand what argv is in this:
int main(int argc, char* argv[]);
Is argv an array of characters? or is it an array of pointers pointing to characters? Either way I am looking for a way to print out the arguments that the user passes to this program. This is the code the I wrote, but it's not printing the argv's so to speak. What's wrong in it? I guess it's my understanding of argv that's making this code incorrect.
#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;
}
After the suggestions that I got from answers, I corrected my code as follows.
#include<stdio.h>
int main(int argc, char *argv[])
{
int i;
printf("%d\n",argc);
for(i=1;i<argc;i++)
{
printf("%s",argv[i]);
}
return 0;
}
And I am using Ubuntu Linux in VMWare on my windows 8.1 pc. This is the output that I am getting. It's just printing argc and after that nothing. What's the problem? Is it the way I am compiling it or something in Linux terminal?
In the above figure, I want the numbers 2,4,5,3 to be printed again, but they are not getting printed.
Thanks.
Upvotes: 23
Views: 119659
Reputation: 8576
Let's explain 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. Now, knowing that arguments start at argv[1]
, your code...
for(int 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 something like...
for(int 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
to stdout
.
Upvotes: 30
Reputation: 474
argv
is a NULL
terminated array of strings. So one doesn't even need argc
to print all the arguments passed to the main function. So if argv
points to NULL
then that's the end of the arguments passed.
So to sum it up, you can do this with a simple while
loop, using only argv
:
while (*argv != NULL)
{
printf("%s\n", *argv);
argv++;
}
Upvotes: 6
Reputation: 106012
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 *
.
Upvotes: 7
Reputation: 13438
Regarding
Is argv an array of characters? or is it an array of pointers pointing to characters?
argv
is an array of c-strings (where each c-string is a pointer to characters). Consider the following command line:
$ your-executable arg1 "arg2 with space"
It would result in an array of strings with the following content (pseudo code)
argv[0] EQUALS "your-executable"
argv[1] EQUALS "arg1"
argv[2] EQUALS "arg2 with space"
As others mentioned, remove the * from printf("%s", *argv[i]);
and fix your loop condition if you want to print all arguments
Upvotes: -1
Reputation: 19120
In your edited question you have fixed your main problem. Now notice that your prompt looks like
./mygrep245YourName@ubuntu:~/test$
Here ./mygrep245
is your output after you printed "5\n"
. You forgot to print line feeds, thus all the output and the subsequent shell output has been concatenated as it is. And the last argument 3
wasn't printed because you put i<argc-1
instead of i<argc
or i<=argc-1
in your loop condition.
Upvotes: 3
Reputation: 172418
You can refer the document:
As you can see, main now has arguments. The name of the variable argc stands for "argument count"; argc contains the number of arguments passed to the program. The name of the variable argv stands for "argument vector". A vector is a one-dimensional array, and argv is a one-dimensional array of strings. Each string is one of the arguments that was passed to the program.
If you need to print it simply remove the * and try this:
#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]); //remove * from here
}
return 0;
}
Upvotes: 1
Reputation: 75062
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?
Upvotes: 4