I am writing some C code on Linux. I want to loop through the *argv[] parameter being passed to main, but I don't know how to stop before getting a seg fault.
i = 0;
while (i < sizeof(argv)) {
printf("%s\n", argv[i]);
i ++;
}
This produces a seg fault because sizeof always returns 8. How do I get the actual number of elements in argv, or apply some kind of test to stop at the end of argv?
The first argument.. argc should already have the CLI argument count.. Any reason why that isn't used?
int main(int argc, char** argv)
{
if(argc > 1)
}
The first argument of main is argc which is the number of arguments passed to your program. This is at least 1, which is the name of the executable.
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("%d\n", argc);
return 0;
}
Invoked as:
$ ./a.out
1
$ ./a.out 1 2 3 4
5
$ ./a.out 1 2 3
4
argc contains the count of parameters in argv.
Related
// test.c
int main(int argc, char* argv[])
{
printf("%s \n", argv[1]);
printf("%s \n", argv[2]);
}
what if I wanna enter
gcc -o test test.c
./test gs -ef
or
./test ls
and so on
When I put in only one argument (ex. ./test date) there is an error message like this (Segmentation fault (core dumped))
When there can come two arguments or one argument in kind like this multiple situations,
How can I code that doesn't print error messages?
argc: Number of arguments passed.
argv: Two-dimensional array that has the arguments passed.
Note that the zeroth position in argv is reserved for the program name, so for example you compiled using gcc -o test test.c, argv[0] will contain test. You could then use argc to loop through argv like so:
while (argc >= 0) {
printf("%s \n", argv[argc]);
argc--;
}
This will of cause print the list of arguments backwards ending with the program name.
Use the argc argument to check the number of arguments and use elements of argv only if there are enough arguments.
#include <stdio.h>
int main(int argc, char* argv[])
{
if (argc > 1) printf("%s \n", argv[1]);
if (argc > 2) printf("%s \n", argv[2]);
}
I ran the following just for fun, but cannot account for the result. Assume ./test WTF? was run at the command line, and the output produced was
WTF? 6 2. Why is there such a vast discrepancy between the reported value of argc (2 - as expected) and strlen(*argv), which came up as 6. I know an array of strings isn't exactly what strlen is looking for, however, I thought the value it produced (if it produced anything) would be reasonably close to argc. Thoughts?
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char**argv)
{
for (int i = 1; i < argc; i++)
{
for (int j = 0; j < strlen(argv[i]); j++)
{
printf("%c", argv[i][j]);
}
printf(" ");
}
printf("\t%lu\t%d", strlen(*argv), argc);
printf("\n");
}
Nothing wrong here. The argv array contains two strings -
program name as invoked --> "./test"
"WTF?".
So in your example strlen(argv[0]) will print 6 and strlen(argv[1]) will print 4.
For example, if you run gcc -o myprog myprog.c in command line, you will get the followings:
argc
4
argv[0]
gcc
argv[1]
-o
argv[2]
myprog
argv[3]
myprog.c
Therefore, for your case you will get 6 (length of ./test for argv[0]) instead of 4 (length of WTF? argv[1]) as you run ./test WTF? in command line.
A follow up question to:
Print 1 to 1000 with out using loop
A question that was asked today and is a duplicate of an older question showing a code snippet of a recursion of the main function :
This code means to count to 10 without using any loops, it does it by recursing on the main functions pointer and when it reaches the needed amount of prints it changes the pointer to the exit function.
#include <stdio.h>
#include <stdlib.h>
void main(int j) {
printf("%d\n", j);
(&main + (&exit - &main)*(j/10))(j+1);
}
Note i changed the number of times the value will be printed,
I do understand that the subtraction of function pointers is UB but still I compiles and ran this function with:
./mainexit 547
And for some reason the values that are beeing printed are from 2 to 10.
when i start the program with ./mainexit 1 it will print until j reaches 10 and then the reference will be for exit but when I run the program with 547 from the beginning the first function in the recursion that is being called located at address 57*&exit so it should do really weird stuff but instead it prints normally. any ideas on how the function returns to the main?
You can do this nonsense like this:
/* Count from 1 to 10 using recursive main call */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int r;
if(argc>=11)
return EXIT_SUCCESS;
printf("argc=%d\n", argc);
r = main(argc+1, NULL);
return r;
}
And you can call
$./countmain
and get:
argc=1
argc=2
argc=3
argc=4
argc=5
argc=6
argc=7
argc=8
argc=9
argc=10
or call
$./countmain a b c d 4 4
and get:
argc=7
argc=8
argc=9
argc=10
But of course it would be much better if you just do something like:
/* Count from 1 to 10 using recursive function call */
#include <stdio.h>
#include <stdlib.h>
void reccount(int to);
int main(int argc, char *argv[])
{
int to;
if(argc==2)
to=atoi(argv[1]);
else
to=10;
reccount(to);
return EXIT_SUCCESS;
}
void reccount(int to)
{
if(to==0)
return;
reccount(to-1);
printf("to=%d\n", to);
return;
}
Now you type:
$ ./reccount.x
to=1
to=2
to=3
to=4
to=5
to=6
to=7
to=8
to=9
to=10
Or you can set the limit as:
$ ./reccount.x 2
to=1
to=2
Now, back to your question:
warning: ‘main’ takes only zero or two arguments [-Wmain]
warning: return type of ‘main’ is not ‘int’ [-Wmain]
If exit had a prototype like main, i.e., int exit(int x, char **y) you could do the trick by adding a conditional like this in the begin of the code:
if(argc==2 && argv!=NULL)
j=atoi(argv[1]);
else
j=argc;
and then calling them as:
(&main + (&exit - &main)*(j/10))(j+1, NULL);
Example:
#include <stdio.h>
#include <stdlib.h>
int myexit(int j, char **p)
{
exit(j);
}
int main(int argc, char **argv)
{
int j;
if(argc==2 && argv!=NULL)
j=atoi(argv[1]);
else
j=argc;
printf("%d\n", j);
(&main + (&myexit - &main)*(j/10))(j+1, NULL);
}
But as it stands, you just cant properly read argv from command line.
The parameter j is not used in the way you think.
When you launch the command, the first argument of main is the number of arg of the command line.
So launching with ./mainexit 547 just pass 2 as the first value of the first call to main. And the loop is built so that it calls exit when j reaches 10.
So the value of your arg is not useful, try ./mainexit hello it will give you the same result!
How do I read command-line parameters in C? For example, in
./test --help
or
./test --build
how do I access "--build" or "--help"?
Your parameters are in argv:
int main(int argc, char **argv)
if you printf the content of argv (argv[0],argv[1] etc) youll get the idea.
try:
int main (int argc, char **argv)
{
for(int i = 0;i< argc;i++)
printf("%s\r\n",argv[i]);
}
You can use the argc and argv arguments to the main function and do different things based on them:
#include <string.h>
void dohelp(void) { /* whatever; */ }
void dobuild(void) { /* whatever; */ }
int main(int argc, char **argv) {
if (argc == 2) {
if (!strcmp(argv[1], "--help")) dohelp();
if (!strcmp(argv[1], "--build")) dobuild();
}
return 0;
}
argc contains the number of parameters passed by the shell to your program, including the program name. So myapp --help gets an argc of 2.
argv are the arguments themselves. The last argv (argv[argc]) is the NULL pointer.
Edit: the parameters don't need to be named argc and argv, but naming else something else is very, very bad!
int main(int foo, char **bar) /* RGAGGGGHH */
int main(int n, char **options) /* RGAGGGGHH */
The very basic is to use the arguments (int argc, char *argv[]) and you can parse those directly.
One more advanced method is to use getopt... http://www.gnu.org/s/libc/manual/html_node/Getopt.html
Command line arguments are arguments passed to your program with its name. For example, the UNIX program cp (copies two files) has the following command line arguments:
cp SOURCE DEST
You can access the command line arguments with argc and argv:
int main(int argc, char *argv[])
{
return 0;
}
argc is the number of arguments, including the program name, and argv is the array of strings containing the arguments. argv[0] is the program name, and argv[argc] is guaranteed to be a NULL pointer.
So the cp program can be implemented as such:
int main(int argc, char *argv[])
{
char *src = argv[1];
char *dest = argv[2];
cpy(dest, src);
}
They do not have to be named argc and argv; they can have any name you want, though traditionally they are called that.
There are several ways to do it [as usual].
Command line arguments are read from argv (passed to main along with argc).
You can parse those yourself and have a bit switch setting flags each time a new option is found in argv. Or you can use a library to parser command line arguments. I suggest libc getopt (google it).
I have made little program for computing pi (π) as an integral. Now I am facing a question how to extend it to compute an integral, which will be given as an extra parameter when starting an application. How do I deal with such a parameter in a program?
When you write your main function, you typically see one of two definitions:
int main(void)
int main(int argc, char **argv)
The second form will allow you to access the command line arguments passed to the program, and the number of arguments specified (arguments are separated by spaces).
The arguments to main are:
int argc - the number of arguments passed into your program when it was run. It is at least 1.
char **argv - this is a pointer-to-char *. It can alternatively be this: char *argv[], which means 'array of char *'. This is an array of C-style-string pointers.
Basic Example
For example, you could do this to print out the arguments passed to your C program:
#include <stdio.h>
int main(int argc, char **argv)
{
for (int i = 0; i < argc; ++i)
{
printf("argv[%d]: %s\n", i, argv[i]);
}
}
I'm using GCC 4.5 to compile a file I called args.c. It'll compile and build a default a.out executable.
[birryree#lilun c_code]$ gcc -std=c99 args.c
Now run it...
[birryree#lilun c_code]$ ./a.out hello there
argv[0]: ./a.out
argv[1]: hello
argv[2]: there
So you can see that in argv, argv[0] is the name of the program you ran (this is not standards-defined behavior, but is common. Your arguments start at argv[1] and beyond.
So basically, if you wanted a single parameter, you could say...
./myprogram integral
A Simple Case for You
And you could check if argv[1] was integral, maybe like strcmp("integral", argv[1]) == 0.
So in your code...
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc < 2) // no arguments were passed
{
// do something
}
if (strcmp("integral", argv[1]) == 0)
{
runIntegral(...); //or something
}
else
{
// do something else.
}
}
Better command line parsing
Of course, this was all very rudimentary, and as your program gets more complex, you'll likely want more advanced command line handling. For that, you could use a library like GNU getopt.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int i, parameter = 0;
if (argc >= 2) {
/* there is 1 parameter (or more) in the command line used */
/* argv[0] may point to the program name */
/* argv[1] points to the 1st parameter */
/* argv[argc] is NULL */
parameter = atoi(argv[1]); /* better to use strtol */
if (parameter > 0) {
for (i = 0; i < parameter; i++) printf("%d ", i);
} else {
fprintf(stderr, "Please use a positive integer.\n");
}
}
return 0;
}
Parsing command line arguments in a primitive way as explained in the above answers is reasonable as long as the number of parameters that you need to deal with is not too much.
I strongly suggest you to use an industrial strength library for handling the command line arguments.
This will make your code more professional.
Such a library for C++ is available in the following website. I have used this library in many of my projects, hence I can confidently say that this one of the easiest yet useful library for command line argument parsing. Besides, since it is just a template library, it is easier to import into your project.
http://tclap.sourceforge.net/
A similar library is available for C as well.
http://argtable.sourceforge.net/
There's also a C standard built-in library to get command line arguments: getopt
You can check it on Wikipedia or in Argument-parsing helpers for C/Unix.