Using strcmp on a vector - c++

I have a vector of strings and I want to compare the first element of the vector with a bunch of different "strings".
Here is what i wanted to do:
if (strcmp(myString[0], 'a') == 0)
but strcmp doesnt work. I basically want to check the contents of myString[0] with a bunch of different characters to see if there is a match. So it would be something like
if (strcmp(myString[0], 'a') == 0){
}
else if (strcmp(myString[0], 'ah') == 0){
}
else ifif (strcmp(myString[0], 'xyz') == 0)
etc..
What can i use to do this comparison? Compiler complains about "no suitable conversion from std:string to "constant char*" exists so i know it doesnt like that im doing a string to char comparison, but i cant figure out how to correctly do this.

std::string overloads operator== to do a string comparison, so the equivalent to
if (strcmp(cString, "other string") == 0)
is
if (cppString == "other string")
So your code becomes (for example)
else if (myString[0] == "ah")

'a' is not a string, it is a character constant. You need to use "a", "ah", "xyz", etc.
Also, if you want to use strcmp, you need to use:
if (strcmp(myString[0].c_str(), "a") == 0)
You can also use the overloaded operator== to compare a std::string with a char const*.
if (myString[0] == "a")

You have marked this post as C++.
compare the first element of the vector with a bunch of different
"strings".
If I am reading your post correctly, the first element of the vector is a std::string.
std::string has a function and an operator to use for string-to-string comparison.
The function is used like:
if (0 == pfnA.compare(pfnB))
As described in cppreference.com:
The return value from std::string.compare(std::string) is
negative value if *this appears before the character sequence specified by the arguments, in lexicographical order
positive value if *this appears after the character sequence specified by the arguments, in lexicographical order
zero if both character sequences compare equivalent
The operator==() as already described, returns true when the two strings are the same.

Related

Can you use strcmp() to check for nullptr value?

Is this piece of code any good to check if a pointer or variable hold a nullptr value?
if(strcmp(variable/pointer, nullptr) == 0){
Do something cool
}
I'm trying to work on some code and I want to know the best way to check if there is a nullptr value present.
Thanks.
I think what you want is
if (!pointer || !variable) {
// do something cool
}
!pointer is essentially the same thing as pointer == nullptr and is considered by some to be better style. See Can I use if (pointer) instead of if (pointer != NULL)?
strcmp is meant to be for C string comparisons. https://www.tutorialspoint.com/c_standard_library/c_function_strcmp.htm
You cannot use strcmp to check whether a variable is equal to nullptr. From strcmp documentation:
Parameters
lhs, rhs - pointers to the null-terminated byte strings to compare
Not only do the input arguments to strcmp need to point to byte strings, they must point to null-terminated byte strings.
Besides, you are making things may more complex than they need to be. You can just use:
if ( variable != nullptr )
{
// Do something
}
else
{
// Do something else
}
strcmp() has undefined behaviour if either argument is a null pointer. Therefore it is necessary to check for null before calling strcmp().
For example, to only call strcmp() if both intended arguments are not null
if (first && second && !strcmp(first, second))
{
// first and second are both non-null, and contain matching strings
}
or (more verbosely, C++11 and later)
if (first != nullptr && second != nullptr && strcmp(first, second) == 0)
{
// first and second are both non-null, and contain matching strings
}
In C++, you'd be better off using the std::string type, rather than messing around with arrays of char, string termination, and functions like strcmp().

C++ if statement not registering "-f" as a possible value

Hey so recently I tried getting a C++ program of mine to take in a parameter "-f" (it helps create a file of data that the user can enter), and so I tried the typical if statement:
if (argv[1] == "-f") { cout << "Please input a file name:" << endl;}
But unfortunately, it doesn't seem to work. The code is registering that "-f" is an argument to add to argc, it just doesn't want to check that it's properly "-f". I even tried atoi to change "f" to 102 and check it via an integer, but it just doesn't seem to be working. Thank you for your time!
argv[1] == "-f" is a pointer comparison. It will never be true because a command line argument will never have the same address as a string literal in your program.
Try if (strcmp(argv[1], "-f") == 0) instead.
Both argv[something] and -f are C-style strings which decay (in most cases) to a pointer to the first character of that string.
Hence a simple comparison, unlike the std::string type, will not work since it will be comparing two distinct pointers. If you want to compare C-style strings, strcmp and its brethren are the way to go.
Otherwise you can turn both those values into actual C++ strings and use the equality operator to compare them.
I'd opt for the former:
if (strcmp (argv[1], "-f") == 0) {
argOneIsMinusF();
}

Less Than operator on string comparison yields same result no matter the situation

I wanted to see if the Less Than operator (<) would work on strings. Well, it did. I started to experiment with it, and it turns out, I got the same result, regardless of the situtaion. The string on the left is always less than the string on the right, even if I swap the strings. Curious on why it did this, I tried to look up what the < operator actually does for strings. I read that it does a lexicographical comparison of the two strings. Still, this did not answer why my code was doing what it was doing. For example:
int main () {
if ("A" < "B")
std::cout << "Yes";
else
std::cout << "No";
return 0;
}
It would output Yes. That makes sense. But when I swap the strings:
int main () {
if ("B" < "A")
std::cout << "Yes";
else
std::cout << "No";
return 0;
}
It would still output Yes. I don't know if I am just being ignorant right now and not fully understanding what is happening here, or if there is something wrong.
It's because a string literal gives you a pointer to a read-only array containing the string (plus its terminator). What you are comparing are not the strings but the pointers to these strings.
Use std::strcmp if you want to compare C-style strings. Or use std::string which have overloaded comparison operators defined.
You are comparing the pointer to the string "A" with the pointer to the string "B".
If you want to compare just the value in the chars then use the single quote 'A' and 'B', if you want to compare strings then use the std::string class std::string("A") < std::string("B") or strcmp()

Why isn't value matching up?

I am having a C++ console application code, which would look up for the condition and then save the text to the (.txt) file.
But the condition is not being applied here. What I have in condition is this:
char command[100];
cin >> command;
if (command == "save") {
fstream file;
file.open("C:\\Users\\AfzaalAhmad\\Documents\\text.txt");
file << "Data you provided was as saved!";
cout << "File Saved!";
}
else {
cout << "Ummm, sir I think there is an error!\n" <<
"The command you entered was: " << command;
}
What I am doing is, to check the command provided by the user, if the command is 'save'
if(command == "save")
then save the data to a file, in the file the data is present when I use this code:
if(command != "save")
Because the command doesnot have to be save, the code executes and gives me the data in the file that is in documents folder.
However, if the else block gets executed, I can still see the correct command 'save' at the end, which is being shown by the code as you can see in the code block.
You can see there, I am using the correct command, but it is not executing as if(command == "save") but it executing if I use this code if(command != "save").
Any guidance please?
command and the string literal "save" are both arrays of chars. They are both being converted to pointers to the first elements (this is called array-to-pointer conversion) and you are comparing those pointers. So what you're really doing with command == "save" is checking if their first characters have the same address.
Instead, to compare C-style strings like you want (checking if all characters in the strings are the same), you need to use std::strcmp. However, a much more preferable solution in C++ is to make command a std::string, instead of an array of char. std::string supports comparison using ==.
In this condition
if (command == "save")
you are trying to compare character arrays. But neither C nor C++ has the comparison operator for arrays. Instead this the string literal and the array in the left part of the operation are implicitly converted to pointers to their first characters and in fact you are comparing two pointers that will be always unequal.
To compare character arrays you should use standard C function std::strcmp that is declared in header <cstring>( in C++ ) or <string.h> (in C)
For example
if ( std::strcmp( command, "save" ) == 0 )
command is a char array, you cannot compare it to a string literal like that (you are actually comparing adresses). If you don't want to use std::string that overload the == operator you could say
strcmp(command, "save"); // it returns zero if equal
Because you should use strcmp to compare C style strings. Or use std::string, which is also better in many other ways, besides being able to compare strings with ==.
A C style string constant is just the address to some memory that holds that particular string, so when you compare command == "save", then for that comparison to be true, command must have the same address as the constant string "save" - which clearly isn't the case ever.
You are comparing the address of command to the address of a string literal. They will never be the same.
Possible solutions:
use the C library function strcpy: if (0 == strcmp(command, "save"))
cast one to a C++ string: if (std::string(command) == "save)
Use a C++14 string literal: if (command == "save"s)
Store the user's input into a C++ string to begin with.
The last of these is the best option, and looks like:
std::string command;
cin >> command;
if (command == "save") {
The variable command is of type char*, because an array in C/C++ is (basically) a pointer (and a fixed maximum array size). Since you are using C++, consider using std::string instead: http://www.cprogramming.com/tutorial/string.html.
What you are using is a C-Style string, and you have to use functions such as strcmp, for example described here: How do I properly compare strings?. But that is the C-way, and, if you're writing C++, you should stick to the std::string class for such purposes.
For comparing c-strings you should use strcmp() function.

Comparison of letters and strings in C++

Why this code
if ("j" > "J")
return false, but this:
string a = "j";
string b = "J";
if (a > b)
return true? Which is the correct answer and how can i fix it?
That is happenig because "j" and "J" are const char []. For exampe "j" is array of chars that
c[0]='j' and c[1]='\0'. In C and C++ you can't compare two arrays.
it is better to use
strcmp("j","J");
witch is in
When you type
string a="j"
you run constructor in class string. But in class string you have overloaded operator< to compare two strings.
You can use single quotes to compare symbols: if ('j' > 'J')
This is because "j" and "J" are string literals, which are compared as const char pointers. The result of the comparison is therefore arbitrary, because the placement of literals in memory is implementation defined.
On the other hand, when you make std::string objects from these string literals, the < operator (along with other comparison operators) is routed to an override provided by the std::string class. This override does a lexicographic comparison of the strings, as opposed to comparing pointer values, so the results of comparison look correct.
You can try
if ("J" < "j")
and may be get a different result.
In fact "J" and "j" are constant C strings and may be placed on .data or .text sections which is determined by the output binary file format. So when you compare them, you are comparing their address in the memory.
But std::string is a C++ class which overloads the > operator, so it's not address/pointer comparing but content comparing.