argc and argv[] in C language [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I'm learning C and in one of the examples we write a program like this:
#include <stdio.h>
int main(int argc, char *argv[])
{
// go through each string in argv
int i = 0;
while(i < argc)
{
printf("arg %d: %s\n", i, argv[i]);
i++;
}
// let's make our own array of stringd
char *states[] = {"California", "Oregon", "Washington", "Texas"};
int num_states = 4;
i = 0; // watch for this
while(i < num_states)
{
printf("state %d: %s\n", i, states[i]);
i++;
}
return 0;
}
and if I run it in terminal like this:
./ex11 test arguments
I get an output of:
arg 0: ./ex11
arg 1: test
arg 2: arguments
state 0: California
state 1: Oregon
state 2: Washington
state 3: Texas
However I don't understand why the "Test argument" part gets printed, i know it has something to do with argc and argv but I don't know how.
Can someone explain this to me (preferably in a simple manner)?

When a command, any command, is run by the shell (actually, any shell) on Unix, then the command line is converted into an array of strings:
cmd_argv[0] = "./ex11";
cmd_argv[1] = "test";
cmd_argv[2] = "arguments";
cmd_argv[3] = NULL;
cmd_argc = 3;
and then invokes:
execvp(cmd_argv[0], cmd_argv);
Note that all I/O redirections are removed, etc. Internally, the system ends up counting the number of non-null pointers at the start of the cmd_argv array and passes them as argv in the new program, and the count as argc. The new program is guaranteed that argc >= 0 and argv[argc] == NULL.
This list is almost the same form as the list of states; the primary difference is that cmd_argv[cmd_argc] is a null pointer, which is certainly not guaranteed with the states data.

That's what your first loop does, it iterates through the strings in argv (which contains the name of the program and the arguments you typed after it), and prints them out. Argc is the number of arguments you passed, or equivalently the length of argv.

argv is the command line arguments, including the executable's name (aguments' values). argc is the amount of elements in argv (argument count).
In your first loop, you are printing the contents of argv, therefore you get the arguments that were passed to your program.

Related

execvp wont print echo command [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am trying to understand execvp command, when i type /bin/ls it print the right output out but not when i print echo something.
char* argumentCommand[11];
char args[10][256]; // inside of this are arguments
//args[0] = echo args[1] = "some text"
//point it to the argument so i can pass it as a vector
for(int i = 0; i<10;i++)
{
argumentCommand[i] = args[i];
}
//wont print anything when i type echo something or wont take the second parameter when i use /bin/ls -l
execvp(argumentCommand[0],argumentCommand);
Does anyone know where the mistake it is?
To wrap this up:
You need to terminate your argument vector argumentCommand with a NULL pointer, and you need to do it at the correct position!
So if you have three arguments:
char* argumentCommand[11];
char args[10][256]; // inside of this are arguments
strcpy(args[0], "ls");
strcpy(args[1], "-l");
strcpy(args[2], "/");
and you fill your argumentCommand-vector like you did:
for(int i = 0; i<10;i++)
{
argumentCommand[i] = args[i];
}
you still have to NULL-terminate it after the third argument:
argumentCommand[3] = NULL;
before executing:
execvp(argumentCommand[0],argumentCommand);
Then it should work as you expect.
Otherwise, the argumentVector is either not NULL-terminated at all, leading to an -EFAULT on execvp(), or it is incidentally NULL-terminated somewhere in memory, which results in the command receiving a number of pseudo-random arguments, leading to unexpected behaviour.
Replace this
execvp(argument[0],argumentCommand);
with
execvp(argumentCommand[0],argumentCommand + 1);
if argumentCommand holds correct executables with valid option & null terminated. For e.g
int main(void) {
char* argumentCommand[] = {"/bin/ls","ls","-l",NULL}; /* Or you can use as you are trying but make sure when you are doing argumentCommand[i] = args[i];, at the end argumentCommand should have valid input */
execvp(argumentCommand[0],argumentCommand + 1);
return 0;
}

Array access args[0][1]-'0' [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have searched for any reference to this for quite a bit now but I haven't had any success, so I thought I would ask here. Basically, I am trying to understand a C written program for creating a shell in linux and I am having problems with this piece of code
...
else if (args[0][0]-'!'==0){
int x = args[0][1]-'0';
int z = args[0][2]-'0';
...
}
The args is storing the command's entered by the user. For instance, later the address space of the child (parent process reads the commands, child executes them) is replaced using a call to execvp(args[0], args). The definition of args is as follows: char *args[MAX_LINE/2 +1];
What I have been having trouble understanding is the ways in which the array is accessed; specifically what is meant by these expressions in this context:
args[0][0]-'!'==0
args[0][1]-'0';
args[0][2]-'0';
Judging by the name of the variable, args stands for a list/array of arguments.
arg[0] is the first element of that array.
args[0][0] is the first character of the first element of that array.
The expression args[0][0]-'!'==0 checks whether that character is equal to '!'. That could have been written better as args[0][0] == '!'.
It's as if instead of using if ( i == 10 ), you decide to use if (i-10 == 0).
The next two lines
int x = args[0][1]-'0';
int z = args[0][2]-'0';
expect that the second and third characters of the first argument are digits and extract the decimal values they correspond to. If the first argument is "!26", then x will have the value 2 and z will have the value 6.
That logic depends on the guarantee that the encoding used for the characters '0' - '9' are required to be contiguous.
Probably args is a reference to
int main(int argc, char **argv);
Then args[0] is the name of the program and in the following args you would find the Arguments of the Programm, see e.g. Arguments to main in C
Thus args[0[0] is the first character of the name of the program.

scanf reading totally different number [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
Here is all the code I have in Visual Studio:
#include <stdio.h>
int main (void) {
int input;
puts("There are 10 seats available on the next flight");
puts("Where would you like to reserve a seat?");
puts("Please type 1 for First Class");
puts("Please type 2 for Economy");
scanf("%d", &input);
if (input == 1) {
printf("You Typed %d\n", &input);
}
if (input == 2) {
printf("You Typed %d\n", &input);
}
}
But when I run the program I get output that says:
There are 10 seats available on the next flight
Where would you like to reserve a seat?
Please type 1 for First Class
Please type 2 for Economy
1
You Typed 6159588
Press any key to continue . . .
I get a totally random number every time. Because of this I can't seem to get anything I write after the input to work. Why is this happening?
What you get printed out is the address of the variable input, not its value! This is because printf accepts its arguments by value - simply because they can be passed like that. What you need thus is
printf("%d", input); // without the ampersand!
scanf - in contrast - is fundamentally different. It is going to place a value into a variable you provide to it - and therefore needs a pointer.
Simple example:
int n = 7;
void myPrintf(int v)
{
++v;
}
void myScanf(int* v)
{
++*v;
}
int main(int argc, char* argv[])
{
myPrintf(n); // n passed by value, cannot be modified
// (but printf does not intend to, either!)
myScanf(&n); // n will be incremented!
// (scanf does modify, thus needs a pointer)
return 0;
}
Back to the roots, though: There is still a fundamental problem: You are passing a pointer, but evaluate it as an int. If sizes of both differ - which is the case on modern 64-bit hardware - you are in trouble. The value then is read from the stack with different size and part of your address actually gets discarded (pointer addresses require "%p" format specifier, assuring that the apprpriate number of bytes is read from stack - in case of modern systems 8 vs. 4 for int).

Filling an Array in C with 0 [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Ive got a problem with this code, im trying to add up array1 with array2.
I enter the numbers for array2 by Command line parameters.
When i enter 10 numbers it is working but when i add less than 10 I get an Memory access error.
My question is now: how do i fill up the missing array fields with the number 0? For example : I enter 9 numbers and the 10th field should be 0.
You are not checking how many command line arguments are passed, and when you index into the command line argument array, you will get an out-of-bounds error.
In you addiren function, you should take advantage of the argc that is passed and used that in your for loop limit.
#include <stdio.h>
#include <stdlib.h>
int addiren(int argc, char**argv){
int array_one[10] = {0,1,1,2,3,5,8,13,21,35};
int array_two[10] = {0}; //Quick way to set the array to all zeros
int array_three[10] = {0};
//Set array_two with your cmd-line args, notice the use of argc
for(int i = 1; i<argc && i<=10; i++){
array_two[i-1] = atoi(argv[i]);
}
//Add array_one with array_two to array_three
for(int i = 0; i<10; i++){
array_three[i] = array_one[i]+array_two[i];
}
//Return an int since that's what the function return type requires
return 0;
}
Hope this helps!

Find the output of a C program [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have been trying solve this question but unable to understand.
If the following program (myprog) is run from the command line as:
myprog friday tuesday sunday
What would be the output?
#include<stdio.h>
int main(int argc, char *argv[]){
while(sizeof argv)
printf("%s",argv[--sizeof argv]);
return 0;
}
The output is-
sunday tuesday friday myprog
Please explain me the output.
Thanx :-)
I am guessing you really what this. It just prints the command line argument out backwards.
#include<stdio.h>
int main(int argc, char *argv[])
{
while (argc)
printf("%s ", argv[--argc]);
printf("\n");
return 0;
}
Disregarding the --sizeof issue, I'm assuming you want to know about the elements of argv.
It contains the arguments and the name of the program. Read any manual or document describing argv.
There are two issues in your code:
--sizeof argv is illegal. It would result in an error.
while(sizeof argv) will result in an infinite loop as the condition will always be true
So in short the code will not compile and will result in an error.
You probably want to understand command line argument processing in C. When you are given some list of program arguments, for example,
myprog friday tuesday sunday
The C language provides arguments to the main() function which provide the number of arguments (4 in this case), and an array of char* (pointers) to these arguments.
Note that sizeof argv is computed at compile time, and the value is the size of a pointer on your system (4 or 8).
First, we explain the arguments to the main function,
int main(
int argc, //an integer count of the number of arguments provided to the program
char* argv[] //an array of pointers to character arguments
)
Your main function is then defined to (apparently) print out the arguments starting at the rightmost argument and working back to the zero-th argument,
{
int argv_sizeof = argc; //you cannot use sizeof argv the way you specified
//argv_sizeof = 4 in your example, but argv[4] is not valid
//argv_sizeof has a value that is one past the rightmost element of argv[]
while( argv_sizeof ) //use argv_sizeof > 0 here; argv_sizeof is 4,3,2,1,0
//when argv_sizeof reaches 0, the while loop terminates
{
printf("%s",argv[--argv_sizeof]); //here you pre-decrement argv_sizeof (3,2,1,0)
//then use argv_sizeof to index into argv[]
//then you print the string at argv[3], argv[2], argv[1], argv[0]
}
//argv_sizeof = 0 here
return 0; //you return the value 0 from the main function
}
Error:
lvalue required as decrement operand
It does not compile.
sizeof is an operator just like + or % and it gives you the size of an object. So, you can't decrement it. Just as somehting like this wouldn't make any sense: --%
The gist of the question is:
What happens if the input is: myprog friday tuesday sunday
When the code does:
index = lastIndex
while(index) // note: while(0) == false
print(array[--index])
So, the output would be the reversal of the elements:
sunday tuesday friday

Resources