Accessing argc in main function of C program - c

I am currently trying to check the number of arguments supplied in the command line before my program executes. However, when I write argc within the main function, argc is underlined in red. When I hover over argc, I see a message saying, "Symbol argc could not be resolved." What could be happening?
int main(int argc, char **argv)
{
printf("%d", argc);
}
I can access argv without any issues. I am using the GCC C Compiler and working in Eclipse in a Unix environment.
EDIT: Renaming argc to something else, restarting Eclipse, and then changing that name back to argc resolved my issue. Thank you to everyone who helped me.

Related

Can I pass parameters to main() in C

Im not sure about how it works but is it possible to pass parameters to a main() function like any other function in C? If so, please explain how it works?
You can't "pass parameters" to it because you can't call it per-se. It's the entry point of your application. It gets parameters from the parent process via the operating system.
int main(int argc, char** argv) is how you receive the arguments. How you "send" them is done by an exec call of some variety, like execv().
This is how your shell sends in arguments, so if you run:
./myprogram arg1 arg2
Then you have those arguments available. Note that argv[0] is the name of the program or the "zeroth" argument, which in this example is the "./myprogram" part.

execve() has a weird behavior depending on the state of an unused variable

I've just recently been exploring the execve() system function. This code might not make much sense but that's not the main focus of this question. (I've managed to make it work correctly since, using this thread).
I've come across a really weird behavior and wanted either an explanation or a confirmation that something like this should not happen.
The "bugged" code is this:
#include <unistd.h>
int main(int argc, char **argv, char **env)
{
if (argc != 2)
return (ERROR_CODE);
char *test[] = { argv[1] };
char *a[] = { NULL };
execve(argv[1], test, env);
return (SUCCESS_CODE);
}
Compiling and executing it with an argument will correctly execute that function, in my case:
$> gcc main.c
$> ./a.out "/bin/ls"
This would work like the ls function would.
Now remove/comment this line:
char *a[] = { NULL };
This variable is clearly not used and completely useless.
Do the same steps once again and for some reason, it doesn't output anything, this one random variable breaks the code for me. (I'm running Ubuntu 20.04 with Gnome 3.36.8 and gcc 9.3.0).
If you need any more information about my OS or anything, feel free to ask.
PS: I think I understand the way the code is trying to work this out but It makes no sense to me.
$> man execve
main(int argc, char *argv[])
char *newargv[] = { NULL, "hello", "world", NULL };
...
execve(argv[1], newargv, newenviron);
The manual example null-terminates "newargv", my idea is that somehow, somewhere, the compiler decided to fuse together my variables "test" and "a", to null-terminate "test"?
Yep, you're accidentally seeing that "fusing" since you're not correctly terminating argv with a NULL and the memory layout happens to be in your favor. If you were less lucky, you'd get garbage in there, or a segfault.
Quoth the manpage (Linux, Darwin), emphasis mine,
The argument argv is a pointer to a null-terminated array of character pointers to null-terminated character strings.
#include <unistd.h>
int main(int argc, char **argv, char **env)
{
if (argc != 2)
return (ERROR_CODE);
char *test[] = { argv[1], NULL };
execve(argv[1], test, env);
return (SUCCESS_CODE);
}
would be the correct invocation.

Code::Blocks command line argument issues

Using:
Code::Blocks Software
Teach Yourself C book
None of "command line argument" example programs work. They either crash or execute with all variables with 0 value or show similar results to the program below.
#include <stdio.h>
int main(int argc, char *argv[])
{
return 0;
}
The simplest of the example program is below.
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for(i=1; i<argc; i++) printf("%s ", arv[i]);
return 0;
}
With a bit of googling I have found that I need to have a Project as a Console Application and then use Project -> set programs arguments, but I have no idea of what to do in the window that pops up.
If you have compiled your project as a console application, you can pass arguments by calling the program from the console (cmd.exe in Windows, terminal in Linux).
The window Project -> set programs arguments simply asks you what arguments do you want to pass to the program when you run the program from Code::Blocks (using the green arrow).
Simply add your arguments in the "Program arguments" text box.

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.

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