I wrote a function where you pass two integers and an operator character ( -*/) and give a result of the two numbers. The code takes the character and checks it using its ascii value. If I pass a number in place of the operator (42 instead of *) then it works, but I don't know how to pass it as a char because the function has int argc and int * argv parameters (the function prototype was written by an instructor.) How do I make it so I can pass the char straight from the command line?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int result;
int main(int argc, char *argv[]){
printf("main_add pid: %d\n", getpid());
int a = 0;
int b = 0;
char c;
//printf("%s\n", argv[1]);
//printf("%s\n", argv[2]);
//printf("%s\n", argv[3]);
a = atoi(argv[1]);
b = atoi(argv[2]);
c = atoi(argv[3]);
if (c=='*'){
result = a * b;
printf("%d * %d = %d\n", a, b, result);
}
else if(c==' '){
result = a b;
printf("%d %d = %d\n", a, b, result);
}
else if(c=='-'){
result = a - b;
printf("%d - %d = %d\n", a, b, result);
}
else if(c=='/'){
result = a / b;
printf("%d / %d = %d\n", a, b, result);
}
else{
printf("fail");
}
}
```[enter image description here][2]
[1]: https://i.stack.imgur.com/X0eiN.png
[2]: https://i.stack.imgur.com/ij5FR.png
CodePudding user response:
the function has int argc and int * argv parameters (the function prototype was written by an instructor.)
That was not written by an instructor, in the sense of having been devised by one of your instructors. int main(int argc, char *argv[])
is one of only two standard variants for the signature of the entry point to a C program, and the only one of them that provides for handling command-line arguments.
How do I make it so I can pass the char straight from the command line?
Your program already receives character data from the command line, in the form of C strings. Why else do you think it makes sense to convert some of those strings to numbers via atoi()
?
But what purpose do you think is served by applying atoi()
to an argument that you do not expect to have the form of a numeric string? That is exactly what produces ...
If I pass a number in place of the operator (42 instead of *) then it works
... which is not what you want.
The argv
array contains pointers to strings from which the characters of the command-line arguments can be read. If you want to read the characters of the arguments then do so directly. For example,
c = argv[3][0];
You would be wise, however, to first verify, by checking the value of argv
, that at least 3 arguments were actually passed. Since argv
also provides the program name, that means you're looking for argv
to be at least 4.
CodePudding user response:
The C standard defines only two valid declarations for the main
function. They are int main(void)
, which is for programs that do not accept command-line inputs and int main(int args, char *argv[])
for programs that do.
In the second case int args
will represent the number of elements in the C-string array char *argv[]
, which is an array of pointers to C-string representations of each of the arguments. As to the how do I pass a character to my program directly from the command line question, you are forced to use the string representation, but this is of little consequence.
Let's assume you compile the program and call it "calculator.elf"
If you were to run: ./calculator.elf 2 7 *
Your main
function would be informed of these arguments by being passed a args
with the value 4, and an argv[]
with four pointers to C strings. The first one would be "./calculator.elf"
, the second "2"
, the third "7"
, and the fourth "*"
.
You are correct by looking in indices 1, 2 and 3 to look for your arguments because you have no need for the name of your program as an argument, and atoi("2")
and atoi("7")
should give you 2 and 7 respectively, but atoi("*")
is not going to give you a useful result because "*"
is not a numerical string.
Keep in mind that "*"
is a string, not a single character, so argv[3]
is going to be a pointer to a '*'
character which is immediately followed by a '\0'
character.
A valid check to see if you were passed "*"
in argv[3]
would be strcmp(argv[3],"*") == 0
or argv[3][0] == '*' && argv[3][1] == '\0'
, but atoi(argv[3])
should return 0 in accordance with the C specification for atoi
in the case that it is passed a pointer to a non-numerical string