Passing Multiple Arguments to main() - c

For my class I need to create a function that takes in multiple parameters at runtime:
void main(int x, int y, int generation, char *layout[20])
However when the program runs with my input for these variables the information is not stored and in the debugging process
run 3 3 3 Test_Round
print x // returns 5
print y // returns -8779
How do I pass multiple arguments into the main function so main will recognize the parameters I give it?
Thanks everyone! I just used argv[1] and so on to get the proper data I need!

The standard is clear about how you need to declare your main function.
From the C99 Standard:
5.1.2.2.1 Program startup
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;9) or in some
other implementation-defined manner.
If they are declared, the
parameters to the main function shall obey the following constraints:
— The value of argc shall be nonnegative.
— argv[argc] shall be a null
pointer.
— If the value of argc is greater than zero, the array
members argv[0] through argv[argc-1] inclusive shall contain pointers
to strings, which are given implementation-defined values by the host
environment prior to program startup. The intent is to supply to the
program information determined prior to program startup from elsewhere
in the hosted environment. If the host environment is not capable of
supplying strings with letters in both uppercase and lowercase, the
implementation shall ensure that the strings are received in
lowercase.
— If the value of argc is greater than zero, the string
pointed to by argv[0] represents the program name; argv[0][0] shall be
the null character if the program name is not available from the host
environment. If the value of argc is greater than one, the strings
pointed to by argv[1] through argv[argc-1] represent the program
parameters.
— The parameters argc and argv and the strings pointed to
by the argv array shall be modifiable by the program, and retain their
last-stored values between program startup and program termination.

void main(int x, int y, int generation, char *layout[20])
is an invalid signature of main(). You need to use
int main(int argc, char *argv[])
where, argv[0] to argv[argc-1] will hold the parameters passed to main().
Quoting C11, chapter §5.1.2.2.2,
If the value of argc is greater than zero, the string pointed to by argv[0]
represents the program name; argv[0][0] shall be the null character if the
program name is not available from the host environment. If the value of argc is
greater than one, the strings pointed to by argv[1] through argv[argc-1]
represent the program parameters.

You can not pass more than two argument in main function. In main function, you can pass only two argument or Zero argument.
Using following parameters, you can pass the value command line.
int main(int argc, char *argv[])

Related

If argc is 1, can I still use argv[1], argv[2],... character arrays?

If there is no argument passed from the command line ie. if argc is 1, can we still allocate memory for argv[1],argv[2],..... and use those buffers for further experiments.
If that is undefined behavior, can I still use it somehow?
No, the C standard does not specify that argv has any elements beyond argv[argc], so they may not exist in C’s object-memory model and the behavior of using them is not defined by the C standard.
C 2018 5.1.2.2.1 2 says:
…
argv[argc] shall be a null pointer.
If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup.
…
That is all there is that defines the extent of the argv array; nothing in the standard says there are more elements.
When argc is one, using argv[1] is defined but using argv[2] is not.
You can store new values to the defined elements because C 2018 5.1.2.2.1 2 also says:
The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.
can I access argv[] elements after argv[argc]?
You can ... but ONLY IN THIS CODE
#include <stdio.h>
int main(int argc, char **argv) {
if (argc == 1) {
char *foo[] = {"bar", "baz", "quux", NULL, "bingo"};
main(3, foo);
} else {
printf("argc is %d; argv[4] is \"%s\"\n", argc, argv[4]);
}
return 0;
}
See code running on ideone.
In all other codes, you cannot.
Always argv[argc] is equal to NULL. In the described case where argc is equal to 1 the array argv contains two pointers argv[0] and argv[1] where argv[1] is a null pointer.
You may reassign the pointers but this does not make a great sense because that will make your program unclear. Instead you could declare your own array if you need.

What does the "main()" that is put in the beginning of programs in C mean?

I just want to learn the basics thoroughly and what some simple codes refer to.
I was able to find a short description at
https://www.dummies.com/programming/c/looking-at-the-c-language/ but I dont think I fully understand it with the help of just that.
It's the starting point for your program. Per 5.1.2.2.1 Program startup of the C standard:
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.
If they are declared, the parameters to the main function shall obey
the following constraints:
The value of argc shall be nonnegative.
argv[argc] shall be a null pointer.
If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to
strings, which are given implementation-defined values by the host
environment prior to program startup. The intent is to supply to the
program information determined prior to program startup from elsewhere
in the hosted environment. If the host environment is not capable of
supplying strings with letters in both uppercase and lowercase, the
implementation shall ensure that the strings are received in
lowercase.
If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the
null character if the program name is not available from the host
environment. If the value of argc is greater than one, the strings
pointed to by argv[1] through argv[argc-1] represent the program
parameters.
The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their
last-stored values between program startup and program termination.

Size of allocated buffer for argv in C Command line argument

When we write a C program that can take command line arguments, we write the main function as:
int main(int argc, char **argv) {
. . .
}
We know argc is greater than equal to 1
So, at least argv[0] exists.
My question is what is size of allocated buffer for argv[0] and subsequent arguments, if any e.g. argv[1], argv[2] etc?
We know argc is greater than equal to 1
Well, that's not true. It shall be non-negative. It can be 0, also.
In case, argv[n] exists, the size of the argv[n] is the size of a pointer in your platform. The size of the memory pointed by the pointer is the same as the supplied command line arguments string (as suppiled by the underlying environment).
Quoting C11, chapter §5.1.2.2.1
The value of argc shall be nonnegative.
and,
If the value of argc is greater than zero, the array members argv[0] through
argv[argc-1] inclusive shall contain pointers to strings, which are given
implementation-defined values by the host environment prior to program startup. The
intent is to supply to the program information determined prior to program startup
from elsewhere in the hosted environment. [...]
If the value of argc is greater than zero, the string pointed to by argv[0]
represents the program name; argv[0][0] shall be the null character if the
program name is not available from the host environment. If the value of argc is
greater than one, the strings pointed to by argv[1] through argv[argc-1]
represent the program parameters.
what is size of allocated buffer for argv[0] and subsequent arguments
The answer is "at least big enough to contain the string pointed at including the null terminator".
For example, on a typical Unix system, with the command
cat /etc/passwd
argc will be two and the buffer allocated to argv[0] will be at least 4 bytes and the buffer allocated to argv[1] will be at least 12 bytes. You cannot assume anything else about the sizes of the buffers or how and where they are allocated. That's all taken care of by the prelude code that runs before main.
I think the full answer is, as said in a comment: it is platform-dependent.
But seems by looking at the source code that at least linux kernel will copy only the necessary bytes to the program stack.
Then there's also no guarantee that your compiler will not do some own magic to the arguments.

Is argv[n] writable?

C11 5.1.2.2.1/2 says:
The parameters argc and argv and the strings pointed to by the argv array shall
be modifiable by the program, and retain their last-stored values between program
startup and program termination.
My interpretation of this is that it specifies:
int main(int argc, char **argv)
{
if ( argv[0][0] )
argv[0][0] = 'x'; // OK
char *q;
argv = &q; // OK
}
however it does not say anything about:
int main(int argc, char **argv)
{
char buf[20];
argv[0] = buf;
}
Is argv[0] = buf; permitted?
I can see (at least) two possible arguments:
The above quote deliberately mentioned argv and argv[x][y] but not argv[x], so the intent was that it is not modifiable
argv is a pointer to non-const objects, so by in the absence of specific wording to the contrary, we should assume they are modifiable objects.
IMO, code like argv[1] = "123"; is UB (using the original argv).
"The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination." C11dr & C17dr1 §5.1.2.2.1 2
Recall that const came into C many years after C's creation.
Much like char *s = "abc"; is valid when it should be const char *s = "abc";. The need for const was not required else too much existing code would have be broken with the introduction of const.
Likewise, even if argv today should be considered char * const argv[] or some other signature with const, the lack of const in the char *argv[] does not completely specify the const-ness needs of the argv, argv[], or argv[][]. The const-ness needs would need to be driven by the spec.
From my reading, since the spec is silent on the issue, yet goes into depth about other assignments of main()'s argv = and argv[i][j] = , it is UB.
Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior" §4 2
[edit]:
main() is a very special function in C. What is allowable in other functions may or may not be allowed in main(). The C spec details attributes about its parameters that given the signature int argc, char *argv[] that shouldn't need. main(), unlike other functions in C, can have an alternate signature int main(void) and potentially others. main() is not reentrant. As the C spec goes out of its way to detail what can be modified: argc, argv, argv[][], it is reasonable to question if argv[] is modifiable due to its omission from the spec asserting that code can.
Given the specialty of main() and the omission of specifying that argv[] as modifiable, a conservative programmer would treat this greyness as UB, pending future C spec clarification.
If argv[i] is modifiable on a given platform, certainly the range of i should not exceed argc-1.
As "argv[argc] shall be a null pointer", assignining argv[argc] to something other than NULL appears to be a violation.
Although the strings are modifiable, code should not exceed the original string's length.
char *newstr = "abc";
if (strlen(newstr) <= strlen(argv[1]))
strcpy(argv[1], newstr);
1 No change with C17/18. Since that version was meant to clarify many things, it re-enforces this spec is adequate and not missing an "argv array elements shall be modifiable".
The argv array is not required to be modifiable (but may be in actual implementations). This is an intentional wording which was reaffirmed in the n849 meeting in 1998:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n849.htm
PUBLIC REVIEW COMMENT #7
[...]
Comment 10.
Category: Request for information/clarification
Committee Draft subsection: 5.1.2.2.1
Title: argc/argv modifiability, part 2
Detailed description:
Is the array of pointers to char pointed to by argv modifiable?
Response Code: Q
This is currently implictly unspecified and the committee
has chosen to leave it that way.
In addition, two separate proposals were made to, respectively, change and augment the wording. Both were rejected. Interested readers can find them by searching for "argv".
argc is just an int and is modifiable without any restriction.
argv is a modifiable char **. It means that argv[i] = x is valid. But it does not say anything about argv[i] being itself modifiable. So argv[i][j] = c leads to undefined behaviour.
The getopt function of C standard library does modify argc and argv but never modifies the actual char arrays.
The answer is that argv is an array and yes, its contents are modifiable.
The key is earlier in the same section:
If the value of argc is greater than zero, the array members argv[0] through
argv[argc-1] inclusive shall contain pointers to strings, which are given
implementation-defined values by the host environment prior to program startup.
From this it is clear that argv is to be thought of as an array of a specific length (argc). Then *argv is a pointer to that array, having decayed to a pointer.
Read in this context, the statement to the effect that 'argv shall be modifiable...and retain its contents' clearly intends that the contents of that array be modifiable.
I concede that there remains some ambiguity in the wording, particularly as to what might happen if argc is modified.
Just to be clear, what I'm saying is that I read this language as meaning:
[the contents of the] argv [array] and the strings pointed to by the argv array shall be modifiable...
So both the pointers in the array and the strings they point to are in read-write memory, no harm is done by changing them, and both preserve their values for the life of the program. I would expect that this behaviour is to be found in all the major C/C++ runtime library implementations, without exception. This is not UB.
The ambiguity is the mention of argc. It is hard to imagine any purpose or any implementation in which the value of argc (which appears to be simply a local function parameter) could not be changed, so why mention it? The standard clearly states that a function can change the value of its parameters, so why treat argc specially in this respect? It is this unexpected mention of argc that has triggered this concern about argv, which would otherwise pass without remark. Delete argc from the sentence and the ambiguity disappears.
It is clearly mentioned that argv and argv[x][x] is modifiable. If argv is modifiable then it can point to another first element of an array of char and hence argv[x] can point to the first element of some another string. Ultimately argv[x] is modifiable too and that could be the reason that there is no need to mention it explicitly in standard.

what is this pointer to a character array supposed to represent [duplicate]

This question already has answers here:
What does int argc, char *argv[] mean?
(12 answers)
Closed 9 years ago.
i am really confused regarding this main function,
int main( int argc, char *argv[] ) {
/*statements*/
}
specifically the
char *argv[ ].
What does that represent exactly? i know that it is a pointer to an array of characters, but how is that array created and how does it work exactly? also is that char array the same as a string, since strings are an array or char?
It is a Command line argument.
You can just pass some values during execution of the program like below.
#include<stdio.h>
int main(int count,char *argv[]){
int i=0;
for(i=0;i<count;i++)
printf("\n%s",argv[i]);
return 0;
}
//save file as arg.c
In command line
C:\tc\bin>arg c JS
Output:
*c*
*JS*
It points to the parameters that are passed to your program when you launch it.
Ex:
./a.out toto tata
printf("argv[0]: %s, argv[1]: %s, argv[2]: %s, argv[3]: %s", argv[0], argv[1], argv[2], argv[3]);
Output:
argv[0]: ./a.out , argv[1]: toto, argv[2]: tata, argv[3]: (null)
argc is the number of arguments stored in argv.
You don't have to care about who created it, as it's part of the C standard. Search information about _start function if you really want to know.
argv is an array of string, and each individual string are each selfs arrays of char.
Some time you will see argv noted like this:**argv or argv[][].
char *argv[] is syntactic sugar for char **argv. argv is simply an array of pointers to null-terminated strings. The operating system creates the array for you before invoking your main() function.
int argc = Number of arguments/parameters when running the program (including program name)
char *argv[] = Arguments as an array of "strings" when running the program. This is how I think of it.
Example:
C:\> echo hello world
argc = 3
argv[0] = echo
argv[1] = hello
argv[2] = world
It points to the parameters passed by executing the java file. If you have a class called MyClass with a main method, by calling java myclass a b, you will have a and b in this array. Also in c or c++ calling myCommand a b...
The crucial facts is that it's an array of pointers to characters not a pointer to an array. So you have several pointers to characters, one per "word" in the program's argument list.
char *argv[] is the same as char **argv and argv[0] to argv[argvc-1] are pointers to C style strings(which are NULL terminated). The draft C99 standard actually provides a nice explanation for how it works and what the contents should be, from section 5.1.2.2.1 Program startup paragraph 2 says:
If they are declared, the parameters to the main function shall obey the following
constraints:
— The value of argc shall be nonnegative.
— argv[argc] shall be a null pointer.
— If the value of argc is greater than zero, the array members argv[0] through
argv[argc-1] inclusive shall contain pointers to strings, which are given
implementation-defined values by the host environment prior to program startup. The
intent is to supply to the program information determined prior to program startup
from elsewhere in the hosted environment. If the host environment is not capable of
supplying strings with letters in both uppercase and lowercase, the implementation
shall ensure that the strings are received in lowercase.
— If the value of argc is greater than zero, the string pointed to by argv[0]
represents the program name; argv[0][0] shall be the null character if the
program name is not available from the host environment. If the value of argc is
greater than one, the strings pointed to by argv[1] through argv[argc-1]
represent the program parameters.
— The parameters argc and argv and the strings pointed to by the argv array shall
be modifiable by the program, and retain their last-stored values between program
startup and program termination.

Resources