How to execute a code whose main function looks like this? - c

The code is like (real noob question) :
int main(int argc, char **argv){
//some code
}
I know, it means I have to give some arguments while executing in the terminal, but the code does not require any arguments or information from the user. I don't know what to give as the argument?

For example:
#include <stdio.h>
int main(int argc, char **argv)
{
printf("Hello World\n");
}
Compile with GCC,
$gcc prog.c -o prog
$./prog
Hello World
So, If you do not use agave in your code, then, there is no need to provide an argument.

I have to give some arguments while executing in the terminal,
No, you don't have to. You may give some arguments. There are conventions regarding program arguments (but these are just conventions, not requirements).
It is perfectly possible to write some C code with a main without argument, or with ignored arguments. Then you'll compile your program into some executable myprog and you just type ./myprog (or even just myprog if your PATH variable mentions at the right place the directory containing your myprog) in your terminal.
The C11 standard n1570 specifies in §5.1.2.2.1 [Program startup] that
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent) or in some other implementation-defined manner.
The POSIX standard specifies further the relation between the command line, the execve function, and the main of your program. See also this.
In practice I strongly recommend, in any serious program running on a POSIX system, to give two argc & argv arguments to main and to parse them following established conventions (In particular, I hate serious programs not understanding --help and --version).

You can always pass some number of arguments or pass nothing unless you are checking for the number of arguments and arguments passed (or forcing compiler to do so). Your command interpreter has no idea what your program is going to do with the passed argument or whether the program need any argument. It's your program which takes care of all these things.
For example,
int main(void){
return 0;
}
you can pass any number of arguments to the above program
$ gcc hello.c -o hello
$ ./hello blah blah blah
In case of
int main(int argc, char **argv){
return 0;
}
you can pass no arguments.
$ gcc hello.c -o hello
$ ./hello
For
int main(int argc, char **argv){
if(argc < 3){
printf("You need to pass two arguments to print those on the terminal\n");
exit(0);
}
else{
printf("%s %s\n", argv[1], arv[2]);
}
return 0;
}
You have to pass two arguments because the program checking the number of arguments passed and using them
$ gcc hello.c -o hello
$ ./hello Hello world

Related

multiple definition of main() function with gcc compilation in c

I'm looking for an efficient (fast and secure) method to communicate multiple scripts (and their associated main function ()) to each other. A bit like the principle of the G-WAN project which uses a launcher (./gwan) to read / load / compile different .c files which each contain (or not) a main() function.
Ideally, my launcher should be able to execute the main () functions of other scripts while sharing information through their argv variables.
But as you know, gcc -Wall script1.c script2.c script3.c -o test return me an error of multiple definition of function main(), and gcc -Wl,--allow-multiple-definition -Wall script1.c script2.c script3.c -o test interprets only the first script1.c main() function.
Maybe the solution would be to have a first script (script1.c) which compiles the other scripts (script2.c and script3.c) via a shared variable?
Thanks for your help and sorry for my limited english.
script1.c:
int main(int argc, char *argv[]){
...
int i = main(argc, argv); // main for script2.c
if(i == 0)
main(argc, argv); // main for script3.c
...
return(0);
}
script2.c:
int main(int argc, char *argv[]){
...
return(0);
}
script3.c:
int main(int argc, char *argv[]){
...
return(0);
}
You can't have multiple main function in c, it's simply not allowed, what you can do is have your main function in your first .c file, and whatever you want in your others .c files.
Then you can write :
#include "script2.c"
#include "script3.c"
on top of your script1.c file.
If you want to compute values inside a file and "send" it to main file, you can do it through functions, defined in your other files, since you include it !
Notice that there is no scripts in C !

Accessing main arguments outside of main on Linux

Is it possible to access the arguments to main outside of main (namely in a shared library constructor) on Linux other than by parsing /proc/self/cmdline?
You can do this by putting the constructor in the .init_array section. Functions in the .init_array (unlike .init) are called with the same arguments main will be called with: argc, argv and env.
Here's a simple example. I used LD_PRELOAD simply to avoid complicating the example with code which actually links and uses a shared library, but it would work in a more normal scenario as well.
file: printargs.c
#include <stdio.h>
static int printargs(int argc, char** argv, char** env) {
puts("In printargs:");
for (int i = 0; i < argc; ++i)
printf(" Arg %d (%p) '%s'\n", i, (void*)argv[i], argv[i]);
return 0;
}
/* Put the function into the init_array */
__attribute__((section(".init_array"))) static void *ctr = &printargs;
Build and use the shared library
(If you use -Wall, you will see a warning, because ctr is unused.)
$ gcc -o printargs.so -std=c11 -shared -fpic printargs.c
$ LD_PRELOAD=./printargs.so /bin/echo Hello, world.
In printargs:
Arg 0 (0x7ffc7617102f) '/bin/echo'
Arg 1 (0x7ffc76171039) 'Hello,'
Arg 2 (0x7ffc76171040) 'world.'
Hello, world.
This solution comes from a suggestion by Mike Frysinger in the libc-help mailing list and there is an even more laconic version of this answer here on SO.

MSVS command line arguments

#include "hmap.h"
int main(char* argv[], int argc)
{
printf("%s", argv[0]); <---- fails here
system("pause");
fileOpen(argv[1]);
return 0;
}
I am using MSVS 2012. I'm wondering if I'm using the command line arguments wrong. The text file is in the same folder. All my header file has is the #include libraries I will using, some #define's I'll be using, and extern function prototypes.
When I run the program it says "expand.exe has stopped working...."
I usually program in a Linux environment using GCC but I'm trying to learn MSVS environment. Getting a little frustrated on how much of a hassle to input command line arguments :.
I think the arguments for main() are around the wrong way.
That is, the first argument should be the argument count (argv), and the second one the argument vector (argv).
int main(int argc, char* argv[]) {}
It fails because a subscript should be used only with an array or pointer.

Handling command line flags in C/C++

I am looking for a very simple explanation/tutorial on what flags are. I understand that flags work indicate a command what to do. For example:
rm -Rf test
I know that the rm command will remove the test folder and that the -Rf flags will force the command to erase not just the folder but the files in it.
But, where are the flags read/compiled??? What handles the flags? Can I, for example, write my own C/C++ program and designate different flags so that the program does different things? I hope I am asking the right questions. If not, please let me know.
At the C level, command line arguments to a program appear in the parameters to the main function. For instance, if you compile this program:
#include <stdio.h>
int main(int argc, char **argv)
{
int i;
for (i = 0; i < argc; i++)
printf("argv[%d] = %s\n", i, argv[i]);
return 0;
}
and invoke it with the same arguments as your example 'rm' command, you get this:
$ ./a.out -Rf test
argv[0] = ./a.out
argv[1] = -Rf
argv[2] = test
As you can see, the first entry in argv is the name of the program itself, and the rest of the array entries are the command line arguments.
The operating system does not care at all what the arguments are; it is up to your program to interpret them. However, there are conventions for how they work, of which the following are the most important:
Arguments are divided into options and non-options. Options start with a dash, non-options don't.
Options, as the name implies, are supposed to be optional. If your program requires some command-line arguments to do anything at all useful, those arguments should be non-options (i.e. they should not start with a dash).
Options can be further divided into short options, which are a single dash followed by a single letter (-r, -f), and long options, which are two dashes followed by one or more dash-separated words (--recursive, --frobnicate-the-gourds). Short options can be glommed together into one argument (-rf) as long as none of them takes arguments (see below).
Options may themselves take arguments.
The argument to a short option -x is either the remainder of the argv entry, or if there is no further text in that entry, the very next argv entry whether or not it starts with a dash.
The argument to a long option is set off with an equals sign: --output=outputfile.txt.
If at all possible, the relative ordering of distinct options (with their arguments) should have no observable effect.
The special option -- means "do not treat anything after this point on the command line as an option, even if it looks like one." This is so, for instance, you can remove a file named '-f' by typing rm -- -f.
The special option - means "read standard input".
There are a number of short option letters reserved by convention: the most important are
-v = be verbose
-q = be quiet
-h = print some help text
-o file = output to file
-f = force (don't prompt for confirmation of dangerous actions, just do them)
There are a bunch of libraries for helping you parse command line arguments. The most portable, but also the most limited, of these is getopt, which is built into the C library on most systems nowadays. I recommend you read all of the documentation for GNU argp even if you don't want to use that particular one, because it'll further educate you in the conventions.
It's also worth mentioning that wildcard expansion (rm -rf *) is done before your program is ever invoked. If you ran the above sample program as ./a.out * in a directory containing only the binary and its source code you would get
argv[0] = ./a.out
argv[1] = a.out
argv[2] = test.c
This simple program should demonstrate the arguments passed to the program (including the program name itself.)
Parsing, interpreting and using those arguments is up to the programmer (you), although there are libraries available to help:
int main(int argc, char* argv[])
{
int i;
for(i=0; i<argc; ++i)
{ printf("Argument %d : %s\n", i, argv[i]);
}
return 0;
}
If you compile this program into a.out, and run it as:
prompt$> ./a.out ParamOne ParamTwo -rf x.c
You should see output:
Argument 0 : a.out
Argument 1 : ParamOne
Argument 2 : ParamTwo
Argument 3 : -rf
Argument 4 : x.c
Actually you can write your own C++ programm which accepts commandline parameters like this:
int main(int argc, char* argv[]){}
The variable argc will contain the number of parameters, while the char* will contain the parameters itself.
You can dispatch the parameters like this:
for (int i = 1; i < argc; i++)
{
if (i + 1 != argc)
{
if (strcmp(argv[i], "-filename") == 0) // This is your parameter name
{
char* filename = argv[i + 1]; // The next value in the array is your value
i++; // Move to the next flag
}
}
}
In your own C program you can process command line options in any way you see fit.
Command line parameters in C come in the parameters of the main(int argc, char *argv[]) method as strings.
And if you'd like to process command line parameters in a way similar to most UNIX commands, the function you're probably looking for is getopt()
Good luck!
The easiest thing is to write your main() like so:
int main(int argc, char* argv[]) { ...
Then inside that main you decide what happens to the command line arguments or "flags". You find them in argv and their number is argc.
flags are arguments passed into the main entry point of the program. For example, in a C++ program you can have
int main(int arc, char* argv[]){
return 0;
}
your arc is the # of arguments passed in, and the pointer gives u the list of actual arguments. so for
rm -Rf test
argc would be 3, and the argv array would contain your arguments. Notice argc >= 1 because the program name itself counts (rm). -RF is your 2nd parameter and test is your third.
So whenever you are typing commands in unix, you essentially are executing programs and passing them parameters that they operate on.
If you are really REALLY interested in the unix OS, you should look up forks and how they work. This can get pretty confusing to a newcomer though, so only if you are really interested in OS and how programs are executed.
GNU libc, which is very likely available on your system, has a library for this called getopt that can be used to parse the options in a sensible fashion. There are examples to get you started in the documentation linked below.
http://www.gnu.org/software/libc/manual/html_node/Getopt.html#Getopt

Reading command line parameters

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.

Resources