check if program argument equals a single character - c

I want to read argument and then compare it with a character:
int main (int argc, char *const argv[]) {
if (argv[1][1] == 'c') {
client();
}
else if (argv[1][1] == 's') {
server();
}
return 0;
}
It works if I type cc or dd, it also works if I type ccttttt. It's just taking the second character, but I'd like it to work only if I type c.

Just change argv[1][1] to argv[1][0] and remember in c/c++ all arrays start in '0'

argv[1] is a pointer to the first command-line argument.
argv[1][1] is the second character of that argument.
The first character is argv[1][0]. (But first check that argc >= 2, i.e., that there actually is a command-line argument.)
Of course this only checks a single character, so it doesn't distinguish between "c" and "cthulhu". If that's how you want to handle the argument, that's fine, but you might want to consider a different approach.

Related

How to detect apostrophe in a char* argument?

I have a c file such that I pass arguments to as such:
./cfile [-size number]
e.g.
./cfile -size 22
Here is an example code for such a file:
int main(int argc, char** argv) {
if (argv[1] != "-size") {
fprintf(stderr, "Wrong format");
return 1;
}
// get_number is some function that returns int value of number if number, NULL otherwise
if (get_number(argv[2]) == NULL) {
fprintf(stderr, "Wrong format");
return 1;
}
return 0;
}
However, when I write
./cfile '-size' '22'
I cannot find a way of making C determine that the apostrophes should not be there.
I want to throw an error due to the apostrophes on each argument, but c seems to treat them as if they are not there.
Is there any way of doing this?
The quotes are interpreted by the shell in order to separate the arguments. They are removed before your program even sees them.
So your program will only see -size for argv[1], not '-size'.
Also, when comparing strings, you need to use strcmp. Using != or == to compare strings is actually comparing pointer values which is not what you want.

comparison between the string and pointer [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 1 year ago.
I'm trying the following codes, but got unexpected result.
//the first element in argv[] is a
int main(int argc, char *argv[]) {
char a;
if (*argv == "a")
{
printf("a");
}
}
I got nothing after excution, so that means the condition *argv++ == "a" is false. So why?
In this if statement
if (*argv == "a")
there are compared two pointers. The first one is the pointer to the first character of the string pointed to by the pointer *argv and the second one is the pointer to the first character of the string literal "a".
As these two strings occupy different extents of memory then the comparison of the pointers always evaluates to logical false.
If you want to compare pointed strings then you need to use the standard C string function strcmp. For example
if ( strcmp( *argv, "a" ) == 0 )
If you want to compare first characters of the strings then you should write
if ( **argv == *"a" )
or just use the character 'a' instead of the string literal that is more natural
if ( **argv == 'a' )
Pay attention to that if *argv is not equal to NULL then this pointer points to the string that denotes the running program.
Maybe you actually mean the following if statement
if ( argc > 1 && strcmp( argv[1], "a" ) == 0 )
if you want to check whether the first command line argument is equal tp the string literal "a".
char *argv[] is an array of pointers to char.
// myapp.c - program to print out all command line parameters
#include <stdio.h>
int main (int argc, char *argv[]) {
int i ;
for (i = 0; i < argc; i++) {
printf ("arg %d = %s\n", i + 1, argv[i]) ;
}
return 0 ;
}
If one were to compile this code and run it at the command line like this:
myapp This That another
It would print out
arg 1 = myapp
arg 2 = This
arg 3 = That
arg 4 = another
So, let's say *argv points to 0x0800001000 (in RAM) and "a" is held at address 0x090000000 (in RAM). What you are doing is like saying:
if (0x0800001000 == 0x090000000) {
...
}
which is always going to be false (unless something really weird happens)
I'm not entirely sure what you want to do, but there are two possibilities
You want to compare the first string passed in on the command line to "a"
// do it like this
if (strcmp(argv[1],"a") == 0) {
...
}
You want to compare the first character of the first string passed in on the command line to 'a'
// do it like this
if (argv[1][0] == 'a') {
...
}
We use argv[1] because argv[0] is just the name of the executable

How to check arguments passed in command line in C?

I am writing a program in C for a basic calculator. I am trying to do this using what I have learned so far: printf() and scanf() functions. I am passing arguments into my program through the command line. I am assuming three arguments will be passed at a time which includes: first int, an operator, and the second int. I want to check if the second arg passed is an operator and then check if it's +,-,*... so on. Here is what I came up with:
int main(int argc, char **argv) {
scanf("%d %c %d", &a, &oper, &b);
if (oper != 43) {
printf("Error: Operator is not a +");
return(1);
}
}
So obviously, I have omitted a lot of the code and kept the relevant part. Here I am just checking if the oper is a +. The ASCII key is 43 so I thought this would work but no luck! Any ideas? (I would like to see if I can do this just with printf and scanf if possible)
EDIT: For example if 12 b 13 was entered, it should return the error above. Same goes for '10 +a 10' or '10 ++ 10'.
Firstly I would highly recommend looking at the man-pages for any C library function you come across, they have a lot of useful information. It seems like you are using scanf() improperly as it is not made to be used with command line arguments.
You can check for matches for a single character by comparing the argument like this:
if(argv[2][0] == '+') ...
(argv[0] is the program's file name).
If would would like to compare string you can use strcmp(). But for the operator example you can get away with just checking the first and second characters in the argument like this:
if(argv[2][0] == '+' && argv[2][0] == '\0') ...
What this does is compare the first two characters of the argument. It first checks for the '+' and then checks if that is the end of the string with by checking for the null terminator '\0'.
We can make the assumption that any argument has at least two characters, the visible character and a null terminator. Performing this on other strings has no guarantee of this however.
The other characters, specifically the numbers need to be converted from their respective ASCII values to integers. You can use atoi or strtol to do this, although atoi will most likely be easier for you.
As David C. Rankin pointed out, **argv is a double pointer which at a high level and in most cases you can treat as a double array. In C a string is actually just an array of type char, so what argv[2] is doing above is first accessing the third index of **argv, this is now de-referenced to a type char * where the string (char array) is located. This can then further be de-referenced by the [0] in argv[2][0] to look at the first char of the string.
Code example:
char **my_arrays = argv; // a array of arrays
char *array = *argv; // de-references to index 0 in argv
char *array = *(argv + 1); // de-references to index 1 in argv
char *array = argv[0]; // de-references to index 0 in argv
char *array = argv[1]; // de-references to index 1 in argv
char first_char = *(*argv) // the first char of the first array of argv
char first_char = *(argv[0]) // the same as above
char first_char = argv[0][0] // the same as above
A side note. All strings in C should end in a null terminator which can be represented by NULL, 0, or '\0' values. This will represent the end of the string and many C functions rely on this to know when to stop.
Also NULL is technically a C macro, but you don't need to treat it any differently than 0 because it literally just expands to 0.
It's char **argv. As Some programmer dude said, you should reread your book/tutorial.
scanf doesn't read arguments. It reads from stdin.
Arguments are of type char* and are stored in argv. To convert these arguments to integers, use atoi or strtol (preferably strtol). See this for more info.
If you want to read from stdin using scanf, that is fine, and what you have will work as long as you instead input the data into stdin, and not as command line arguments.

Command line arguments that has options [duplicate]

This question already has answers here:
How to properly compare command-line arguments?
(4 answers)
Closed 4 years ago.
So I have to write a program that contains two possible options depending on what the user chooses by entering either -i or -w. I'm very new to command line arguments in general and I have no idea how to do this. So far I have:
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argc == -'i') {
puts("Test 1");
}
else if(argc == -'w') {
puts("Test 2");
}
return 0;
}
It doesn't print anything...
Any explanation is greatly appreciated. I'm just trying to understand the logic behind this.
First of all, you are comparing oranges with appels. argc stores the number of
arguments. Second, even if you used argv[1], the comparison would be still
wrong, because it would be comparing pointers, not the contents. Note that in C
a string is a sequence of characters that terminates to '\0'-terminating byte.
A char* variable only points to the start of that sequence. The == operator
checks for equality of values, in case of pointers (and string literals), it
compares whether both pointers point to the same location.
When you want to compare strings, you have to compare the strings themselves,
that means you have to compare the contents where the pointers are pointing to.
For strings you have to use the strcmp function like this:
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argc != 2)
{
fprintf(stderr, "usage: %s option\n", argv[0]);
return 1;
}
if(strcmp(argv[1], "-i") == 0)
puts("Test 1");
else if(strcmp(argv[1], "-w") == 0)
puts("Test 2");
else {
fprintf(stderr, "Invalid option '%s'\n", argv[1]);
return 1;
}
return 0;
}
Note that it is important to check first that you have enough command line
arguments (the first if of my code). If the user didn't pass any argument,
argc will be 1 and argv[1] will point to NULL, which would yield undefined
behaviour if it is passed to strcmp. That's why I only do strcmp when I'm
100% sure that argv[1] is not NULL.
Also if you are coding for a POSIX system (linux, mac, etc), then I recommend using
getopt for parsing of the command line arguments.
You have to check argv[i] where i is the array number of the command line argument being put in, argv[0] would be the file name called upon and after that argv[1] would be the first statement, argv[2] the next and so on
argc means "argument count". meaning the number of arguments
argv is a 2-dimensional array. Strings are 1-dimensional character arrays in C. The second dimension comes from you having multiple String.
So if you want the first String argument, you would access it as follows:
argv[0]
You are also attempting to compare strings, which are more than 1 character long. You should use strcmp to compare strings in C. See How do I properly compare strings?
and if you want to compare equality, you would not use ==, == is for basic data types such as int or char.
argc represents the number of parameters that were passed in at the command line including the program name itself.
In c, a character, e.g., 'i' is an 8-bit number representing the ASCII code of the letter i. So your conditional statement if(argc == -'i') is actually checking whether -105 (105 is the ascii value of the letter i) is the number of arguments that was passed to your program.
To check whether the arguments passed in are "-i" or "-w" you need to perform string comparison, using the c library functions or your own algorithm, and you need to be comparing those strings to argv[i] (where i is the position of the parameter you're checking in the program invocation)
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("The name of the program is %s\n", argv[0]);
if( strcmp(argv[1], "-i") == 0 ) { puts("Test 1"); }
if( strcmp(argv[1], "-w") == 0 ) { puts("Test 2"); }
return 0;
}

Fail to check the second character in argv[] in C

I would like to check the arguments in argv[], but it fails to check the second character.
For example,
I can do that:
int main(int argc, char *argv[]){
if (*argv[1] == "A")
printf("Hello: %s\n", argv[1]);
}
However, I can't check argv[1] when I change "A" to "AB" like this:
if (*argv[1] == "AB")
printf("Hello: %s\n", argv[1]);
}
Strings are compared with strcmp() in C, almost never with ==:
if(strcmp(argv[1], "AB") == 0)
printf("the second argument is AB\n");
Note that 0 is returned when the compared strings are equal.
On this line:
if (*argv[1] == "AB")
you're comparing a char to char*. These are different types. Also, even if the first operand was char* you should still not use == to compare strings since it merely compares the pointer values. Use strncmp() instead
if (strncmp("AB", argv[1], 2) == 0)
This condition is true if two first characters of argv[1] are "AB", e.g. if argv[1] is "ABC". If you want to check that argv[1] is exactly "AB" use strcmp() like this
if (strcmp("AB", argv[1]) == 0)
Note that it is fine to use == to compare single characters:
if (argv[1][0] == 'A')
Also, before you assume argv[1] is valid you should check argc to ensure you have actually been given an argument.
*argv[1] is a char. you should not compare it to string (char*). If you want you check if it's A, do if (*argv[1]=='A') If you want to check the whole argument, do it like strcmp(argv[1],"AB")
You should stop comparing pointers and characters, this isn't healthy.
You can do *argv[1]=='A'. And when it comes two two characters, you should use strncmp.

Resources