Why directly comparing string fails, but succeeds using char* [duplicate] - c

This question already has answers here:
Using the equality operator == to compare two strings for equality in C [duplicate]
(9 answers)
Closed 8 years ago.
In the following working code; instead of using *tofind, if I directly use the comparison
if(*argv[i] == "and")
it fails.
Why would that be?
/**
* Find index of the word "and"
* ./a.out alice and bob
*/
int main(int argc, char **argv) {
int i = 0;
char *tofind = "and";
while (argv[i] != NULL) {
if(*argv[i] == *tofind) {
printf("%d\n", i + 1);
break;
}
++i;
}
return 0;
}

if(*argv[i] == "and") shouldn't compile, I think you mean if (argv[i] == "and"), that would compare the pointers of the two, not the string content.
if (*argv[i] == *tofind) doesn't work as you expected either, it only compares the first character.
To compare strings, use strcmp():
if (strcmp(argv[i], tofind) == 0)

A "char*" is officially a pointer to a single char, for example to find points to a letter 'a'. You know that there are two more chars and a nul char, but officially it points to a single char.
Therefore, *argv[i] is the first character of an argument, and *tofind is always the letter 'a', so your code checks if the first character of an argument is an 'a'. Look at the strcmp function, which compares whole strings.

look at the type of
*argv[i] //its type is char
and of "and"
"and" //its type is const char * as it is decayed into pointer
so thats why you are unable to compare them.
while the type of
*tofind
is char and you can now compare the two.for more details see FAQs section 6.

Related

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.

Searching for an element in 2D array, C programming

I'm a noob at C programming and I'm having some difficulties making a string list and searching for a specific element.
#include <stdio.h>
#include <string.h>
# define MAX 6
int main(){
char word[MAX];
char x[MAX][20];
int i;
strcpy(x[0], "One");
strcpy(x[1], "Two");
strcpy(x[2], "Three");
strcpy(x[3], "Four");
strcpy(x[4], "Five");
strcpy(x[5], "Six");
printf("%s", "Search:");
scanf("%s", word);
for (i=0; i<6; i++) {
if (x[i] == word) {
printf("%s", "Found a match!");
}
}
return 0;
}
It's never executing the statement present in the if block (i.e, printf("Found a match!")) . Any idea why it is not executing the above mentioned statement?
Thanks!
Use
if(strcmp(x[i],word) == 0)
printf("Found match\n");
== can't be used to compare strings as you are doing it.
This only compares the pointers and not the strings
It never returns "Found a match!". Any idea why?
Reason:
In C, array names are converted to pointers to their first elements ( with some exceptions there). x[i] == word is comparing two pointers instead of comparing strings. Since the base addresses of both arrays are different, comparison returns a false value.
Correction:
Use strcmp to compare two strings.
This
if (x[i] == word)
should be
if (strcmp(x[i], word) == 0)
In c a predefined function is present in string.h library it is strcmp as stated by other users function int strcmp(const char *str1, const char *str2) compares the string pointed to bystr1 to the string pointed to by str2.u can write your own function for comparing strings and use it.
I want you to conceptually understand why we can't use == in c unlike c++ as c don't contain anything like string class(c is purely procedural) so that u can create object of it and use it.hence c uses char array to represent a string .if u examine ur code x[i] == word compares starting addresses of char arrays/strings x[i],word. I believe u understood the concept . now I want to explain that u can use pointers here i.e
if (*x[i] == *word)
printf("Found a match!");
Works fine as u can understand that here we are comparing two strings directly by pointing to their address locations.sorry if I have provided unwanted info due to my inexperience in SO as this my first answer in SO.
use strcmp() function for comparing two string. when two string is match its result is 0.
so you can change like :
if ( ! strcmp(word,x[i]) ) // when match result will be `! 0 = 1`
printf("Found Match\n");
in the C programming language, the == operator is not working for comparing strings(as others wrote before me). I advice to try using a really nice feature in C++ called string. It is builded in the standard library, and with this, you can use the == operator for comparing.
#include <iostream>
using namespace std;
int main(void)
{
string a = "Apple";
if( a == "Apple" ) cout << "This is working" << endl;
}

Checking equality of a string in C and printing an answer [duplicate]

This question already has answers here:
C Strings Comparison with Equal Sign
(5 answers)
Closed 9 years ago.
i've written some simple code as an SSCCE, I'm trying to check if string entered is equal to a string i've defined in a char pointer array, so it should point to the string and give me a result. I'm not getting any warnings or errors but I'm just not getting any result (either "true" or "false")
is there something else being scanned with the scanf? a termination symbol or something? i'm just not able to get it to print out either true or false
code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define LENGTH 20
//typedef char boolean;
int main(void)
{
const char *temp[1];
temp[0] = "true\0";
temp[1] = "false\0";
char var[LENGTH];
printf("Enter either true or false.\n");
scanf("%s", var);
if(var == temp[0]) //compare contents of array
{
printf("\ntrue\n");
}
else if(var == temp[1]) //compare contents of array
{
printf("\nfalse\n");
}
}
const char *temp[1];
This defines tmp an array that can store 1 char* element.
temp[0] = "true\0";
Assigngs to the first element. This is okay.
temp[1] = "false\0";
Would assign to the second element, but temp can only store one. C doesn't check array boundaries for you.
Also not that you don't have to specify the terminating '\0' explicitly in string literals, so just "true" and "false" are sufficient.
if(var == temp[0])
This compares only the pointer values ("where the strings are stored"), not the contents. You need the strcmp() function (and read carefully, the returned value for equal strings might not be what you expect it to be).
Use strcmp for comparing strings:
#include <stdio.h>
int main(void)
{
const int LENGTH = 20;
char str[LENGTH];
printf("Type \"true\" or \"false\:\n");
if (scanf("%19s", str) != 1) {
printf("scanf failed.");
return -1;
}
if(strcmp(str, "true") == 0) {
printf("\"true\" has been typed.\n");
}
else if(strcmp(str, "false") == 0) {
printf("\"false\" has been typed.\n");
}
return 0;
}
and also note that:
string literals automatically contain null-terminating character ("true", not "true\0")
const int LENGTH is better than #define LENGTH since type safety comes with it
"%19s" ensures that no more than 19 characters (+ \0) will be stored in str
typedef char boolean; is not a good idea
unlikely, but still: scanf doesn't have to succeed
and there is no #include <iostream> in c :)
== checks for equality. Let's see what you're comparing.
The variable var is declared as a character array, so the expression var is really equivalent to &var[0] (the address of the first character in the var array).
Similarly, temp[0] is equivalent to &temp[0][0] (the address of the first character in the temp[0] array).
These addresses are obviously different (otherwise writing var would automatically write temp[0] as well), so == will always return 0 for your case.
strcmp, on the other hand, does not check for equality of its inputs, but for character-by-character equality of the arrays pointed to by its inputs (that is, it compares their members, not their addresses) and so you can use that for strings in C. It's worth noting that strcmp returns 0 (false) if the strings are equal.

C String Comparison Failure? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C String — Using Equality Operator == for comparing two strings for equality
I have the following code;
#include <stdio.h>
#define MAXLINE 2600
char words[4][MAXLINE];
int i;
int main(){
printf("Enter menu option: ");
scanf("%s", words[i]);
printf ("\n %s was entered!", words[i]);
if (words[i]=="help"){
printf("\nHelp was requested");
}
else
{
printf("\nCommand not recognized!");
}
}
The array evaluation in the if statement isn't working. I am obviously doing something wrong. Can someone explain to me what?
You are comparing words[i] and "help" for pointer equality, not string equality. I think you meant: if (strcmp(words[i], "help") == 0) {
In C, strings (sequences of characters) are treated as arrays of characters. As a result, you shouldn't compare arrays using the == operator.
The array braces [] are just syntactic sugar to hide the pointer arithmetic that's going on under the hood. In general, arr[i] is identical to *(arr + i). Using this information, let's take a look at your comparison:
words[i] -> *(words + i), which is a pointer to an array of characters.
If you want to compare strings, use strncmp.

Resources