Can anyone pls let me know the exact c++ code of case sensitive comparison function of string class?
How about?
std::string str1, str2;
/* do stuff to str1 and str2 */
if (str1 == str2) { /* do something */ }
Or
if (str1.compare(str2) == 0) { /* the strings are the same */ }
std::string str1("A new String");
std::string str2("a new STring");
if(str1.compare(str2) == 0)
std::cout<<"Equal"; // str1("A new String") str2("A new String");
else
std::cout<<"unEqual"; //str1("A new String") str2("a new STring")
compare() returns an integral value rather than a boolean value. Return value has the following meaning: 0 means equal, a value less than zero means less than, and a value greater than zero means greater than
== is overloaded for string comparison in C++ AFAIK (unlike in Java, where u have to use myString.equals(..))
If you want to ignore case when comparing, just convert both strings to upper or lower case as explained here: Convert a String In C++ To Upper Case
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str1 ("green apple");
string str2 ("red apple");
if (str1.compare(str2) != 0)
cout << str1 << " is not " << str2 << "\n";
if (str1.compare(6,5,"apple") == 0)
cout << "still, " << str1 << " is an apple\n";
if (str2.compare(str2.size()-5,5,"apple") == 0)
cout << "and " << str2 << " is also an apple\n";
if (str1.compare(6,5,str2,4,5) == 0)
cout << "therefore, both are apples\n";
return 0;
}
I got it from http://www.cplusplus.com/reference/string/string/compare/
Hope google work !!
But use == operator like
s1 == s2 would also work good
Related
Lets just say string A = "ABCDEF", string B = "ABC"
Is there a way to compare both these strings character by character?
For example:
Lets say you wanted to iterate through each string,
for(size of strings)
if(A.at(i) == B.at(i)
{
do something
}
else
{
do something else
}
You couldn't do it in a for loop since they're different sizes, any other suggestions?
You couldn't do it in a for loop since they're different sizes,
You absolutely can do it in a loop. You can use the following algorithm:
Compare lengths of the strings
Store the shorter length in n
Do n iterations in loop
Decide what you want to do with rest of the longer string
You could also take a look at something like std::lexicographical_compare. It is used to sort words as they would be sorted in the dictionary. If you want to ensure that characters themselves are sorted in a different order, you can provide a function that does that comparison. For example, let's imagine that you want a letter 'c' to actually be sorted as a 'k'. You can accomplish that in the following manner:
bool comp(char c1, char c2)
{
c1 = std::tolower(c1);
c2 = std::tolower(c2);
c1 = (c1=='c') ? 'k' : c1;
c2 = (c2=='c') ? 'k' : c2;
return c1 < c2;
}
// main.cpp
std::string str1 = "string c";
std::string str2 = "string d";
std::string str3 = "string k";
std::cout << std::boolalpha;
std::cout << str1 << ( std::lexicographical_compare(str1, str2, comp) ? "<" : ">=" ) << str2 << std::endl;
std::cout << str1 << ( std::lexicographical_compare(str1, str3, comp) ? "<" : ">=" ) << str3 << std::endl;
std::cout << str2 << ( std::lexicographical_compare(str2, str3, comp) ? "<" : ">=" ) << str3 << std::endl;
if you use std::string, for comparison you can either use the compare function or use relational operators, provided with this class.
std::string str1 ("green apple");
std::string str2 ("red apple");
if (str1.compare(str2) != 0)
std::cout << str1 << " is not " << str2 << '\n';
or
if (str1 != str2) std::cout << "str1 and str2 are not equal\n";
all other relational operators, i.e., == < > <= >= are also available. It looks like in your case you only need == of !=.
if you insist on comparing strings char by char, than you can do it in a loop in several ways. For example,
bool equal = true;
if (str1.length() != str2.length())
equal = false;
else
for (int i = 0; equal && i < str1.length(); i++)
if (str1.at(i) != str2.at(i)
equal = false;
Say you have a std::string and a boost::container::string just like this :
std::string stdString = "This is a test";
boost::container::string boostString = "This is a test";
Say you want to compare their content ; the following is not possible because we cannot compare their types :
stdString == boostString // no operator "==" matches these operands
You then choose to use both of their methods .c_str() to get a char* from each string. Not being sure if this does effectivly compare the strings, you try it :
stdString.c_str() == boostString.c_str() // compiles, but comparison returns false
You then try to only use c_str() method from the std::string :
stdString.c_str() == boostString // compiles, and comparison seems fine
You try the opposite out of curiosity and it works as well :
stdString == boostString.c_str() // compiles, and comparison seems fine
So the question is, why does these two latter comparisons seem to work fine when the first one did not ?
Bonus question : Is this an unreliable way of comparing the content of these strings ?
Full code sample :
#include <boost/container/string.hpp>
#include <iostream>
int main(int argc, char *argv[])
{
std::string stdString = "This is a test";
boost::container::string boostString;
for (int i = 0; i < 2; ++i)
{
if (i == 0)
{
boostString = "This is a test";
std::cout << "Both strings have the same content." << std::endl << std::endl;
}
else
{
boostString = "This is z test";
std::cout << std::endl << std::endl;
std::cout << "Both strings are different from each other." << std::endl << std::endl;
}
std::cout << "stdString.c_str() == boostString.c_str() comparison is : ";
if (stdString.c_str() == boostString.c_str())
std::cout << "true" << std::endl;
else
std::cout << "false" << std::endl;
std::cout << "stdString.c_str() == boostString comparison is : ";
if (stdString.c_str() == boostString)
std::cout << "true" << std::endl;
else
std::cout << "false" << std::endl;
std::cout << "stdString == boostString.c_str() comparison is : ";
if (stdString == boostString.c_str())
std::cout << "true" << std::endl;
else
std::cout << "false" << std::endl;
}
return 0;
}
Output given by the sample :
> Both strings have the same content.
>
> stdString.c_str() == boostString.c_str() comparison is : false
> stdString.c_str() == boostString comparison is : true
> stdString == boostString.c_str() comparison is : true
>
>
> Both strings are different from each other.
>
> stdString.c_str() == boostString.c_str() comparison is : false
> stdString.c_str() == boostString comparison is : false
> stdString == boostString.c_str() comparison is : false
With stdString.c_str() == boostString.c_str() you don't compare the strings, you compare the pointers returned by each objects c_str function. And they will most certainly not be equal. If you want to compare strings C-style use std::strcmp.
The reason e.g. stdString.c_str() == boostString works is because boost::container::string have a non-explicit constructor taking a const char* argument, just what stdString.c_str() is returning. That means stdString.c_str() == boostString is actually equal to boost::container::string(stdString.c_str()) == boostString, which compares two boost::container::string objects.
Same for stdString == boostString.c_str(), it's equal to stdString == std::string(boostString.c_str()).
If you need to mix std::string and boost::container::string, and need to use some specific operators with that mix, then you can always overload those operators yourself.
For example
bool operator==(std::string const& stdString, boost::container::string const& boostString)
{
// If the length of the strings differs, then they're not equal and we return false
// Otherwise, compare the actual contents of the strings
return stdString.length() == boostString.length() &&
std::memcmp(stdString.c_str(), boostString.c_str(), stdString.length()) == 0;
}
bool operator==(boost::container::string const& boostString, std::string const& stdString)
{
return stdString == boostString; // Calls the previously defined operator== overload
}
Both are needed so you can use either type on either side of ==.
Also note that I'm using std::memcmp for the comparison, because either string could contain embedded zeros, which would otherwise act as the string terminator for std::strcmp.
I'm working on my C++ assignment. I'm having an issue with string comparison.
I'm comparing two apparently identical strings using == operating but the condition returns false. The debugger also shows that both strings (stored in different variables) are identical. I must be missing something.
Here is my code:
void classCounter() {
ifstream fread;
string linetxt;
char *records[50];
char myLine[100];
char delims[] = "|";
int btotal=0,etotal=0,total=0;
fread.open("F:\\myfile.txt");
while(!fread.eof()) {
getline(fread,linetxt,'\n');
int i = 0;
strcpy(myLine, linetxt.c_str());
records[i] = strtok( myLine, delims );
while( records[i] != NULL )
{
cout << records[i] << "|";
char *bu = "Business";
if(records[i] == bu) {
btotal++;
}
if(records[i] == "Economy") {
etotal++;
}
//printf("%d '%s'\n", i, records[i]);
records[++i] = strtok( NULL, delims );
break;
}
total++;
}
cout << "Total number of booked Business seats: " << btotal << endl;
cout << "Total number of booked Economy seats: " << etotal << endl;
cout << "Total number of booked seats: " << total << endl << endl;
}
Here is what debugger shows:
Both if conditions are returning false.
Please suggest what could be the issue.
You are comparing two pointers, and they will never be the same. Either heed the advice to use std::string (what I recommend too) or you use strcmp to compare strings.
if(records[i] == bu) {
and
if(records[i] == "Economy") {
compare two char*, not strings.
You can compare them as strings by using std::string or using the function strcmp.
Option 1: Use std::string
std::string records[50];
With that change,
if(records[i] == bu) {
and
if(records[i] == "Economy") {
should work.
Option 2: Use strcmp
if( strcmp(records[i], bu) == 0) {
and
if( strcmp(records[i], "Economy") == 0) {
Your debugger is telling you what you need to know.. You're using char* instead of String so your char* are pointers. Your program is comparing two pointers and 0x00c93bc0 != 0x002af824.
Use strcmp in the future to avoid this problem
So I'm going to assume your input file looks something like:
Business|Economy|Economy|Economy|Business
Economy|Economy|Economy|Business|Economy
...and so on. Correct? And you're trying to count up how many of each kind of ticket was sold?
If so, I'd write the code quite a bit differently. I'd probably do something like this:
std::map<std::string, int> tickets;
std::string name;
std::ifstream in("f:/myfile.txt");
int total = 0;
while (std::getline(in, name, '|')) {
++tickets[name];
++total;
}
for (auto t : tickets)
std::cout << "Total number of booked " << t.first << " seats is: " << t.second "\n";
std::cout << "Total number of booked tickets: " << total << "\n";
I have two strings srt1 and str2 as:
std::string str1 = "20110627120000";
std::string str2 = "20110629120000";
All I need is to convert them into time format and compare which one is greater.
And I am using below code for it but I am getting segmentation fault:
tm tm1,tm2;
sscanf(str1.c_str(),"%4d%2d%2d %2d%2d%2d",&tm1.tm_year,&tm1.tm_mon,&tm1.tm_mday,&tm1.tm_hour,&tm1.tm_min,&tm1.tm_sec);
sscanf(str2.c_str(),"%4d%2d%2d %2d%2d%2d",&tm2.tm_year,&tm2.tm_mon,&tm2.tm_mday,&tm2.tm_hour,&tm2.tm_min,&tm2.tm_sec);
std::cout << "5 \n";
if ((tm1.tm_year < tm2.tm_year) && (tm1.tm_mon<tm2.tm_mon) && (tm1.tm_mday<tm2.tm_mday ))
{
std::cout << str2 <<"is greater \n";
}
Why do you convert the strings when they are perfectly comparable?
int main()
{
std::string str1 = "20110627120000";
std::string str2 = "20110629120000";
std::cout << ((str1 < str2) ? "True" : "False") << std::endl;
}
Using sscanf with the format having a space in between "%4d%2d%2d %2d%2d%2d" looks plain wrong. Not checking the result of it, is.
Dates in the format you specified can be easily converted to integers and then compared. See below:
#include <iostream>
int main()
{
unsigned long long date_a = std::stoull("20110627120000");
unsigned long long date_b = std::stoull("20110629120000");
std::cout << std::max(date_a, date_b) << std::endl;
return 0;
}
I would like to compare a character literal with the first element of string, to check for comments in a file. Why use a char? I want to make this into a function, which accepts a character var for the comment. I don't want to allow a string because I want to limit it to a single character in length.
With that in mind I assumed the easy way to go would be to address the character and pass it to the std::string's compare function. However this is giving me unintended results.
My code is as follows:
#include <string>
#include <iostream>
int main ( int argc, char *argv[] )
{
std::string my_string = "bob";
char my_char1 = 'a';
char my_char2 = 'b';
std::cout << "STRING : " << my_string.substr(0,1) << std::endl
<< "CHAR : " << my_char1 << std::endl;
if (my_string.substr(0,1).compare(&my_char1)==0)
std::cout << "WOW!" << std::endl;
else
std::cout << "NOPE..." << std::endl;
std::cout << "STRING : " << my_string.substr(0,1) << std::endl
<< "CHAR : " << my_char2 << std::endl;
if (my_string.substr(0,1).compare(&my_char2)==0)
std::cout << "WOW!" << std::endl;
else
std::cout << "NOPE..." << std::endl;
std::cout << "STRING : " << my_string << std::endl
<< "STRING 2 : " << "bob" << std::endl;
if (my_string.compare("bob")==0)
std::cout << "WOW!" << std::endl;
else
std::cout << "NOPE..." << std::endl;
}
Gives me...
STRING : b
CHAR : a
NOPE...
STRING : b
CHAR : b
NOPE...
STRING : bob
STRING 2 : bob
WOW!
Why does the function think the sub-string and character aren't the same. What's the shortest way to properly compare chars and std::string vars?
(a short rant to avoid reclassification of my question.... feel free to skip)
When I say shortest I mean that out of a desire for coding eloquence. Please note, this is NOT a homework question. I am a chemical engineering Ph.D candidate and am coding as part of independent research. One of my last questions was reclassified as "homework" by user msw (who also made a snide remark) when I asked about efficiency, which I considered on the border of abuse. My code may or may not be reused by others, but I'm trying to make it easy to read and maintainable. I also have a bizarre desire to make my code as efficient as possible where possible. Hence the questions on efficiency and eloquence.
Doing this:
if (my_string.substr(0,1).compare(&my_char2)==0)
Won't work because you're "tricking" the string into thinking it's getting a pointer to a null-terminated C-string. This will have weird effects up to and including crashing your program. Instead, just use normal equality to compare the first character of the string with my_char:
if (my_string[0] == my_char)
// do stuff
Why not just use the indexing operator on your string? It will return a char type.
if (my_string[0] == my_char1)
You can use the operator[] of string to compare it to a single char
// string::operator[]
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str ("Test string");
int i; char c = 't';
for (i=0; i < str.length(); i++)
{
if (c == str[i]) {
std::cout << "Equal at position i = " << i << std::endl;
}
}
return 0;
}
The behaviour of the first two calls to compare is entirely dependent on what random memory contents follows the address of each char. You are calling basic_string::compare(const char*) and the param here is assumed to be a C-String (null-terminated), not a single char. The compare() call will compare your desired char, followed by everything in memory after that char up to the next 0x00 byte, with the std::string in hand.
Otoh the << operator does have a proper overload for char input so your output does not reflect what you are actually comparing here.
Convert the decls of and b to be const char[] a = "a"; and you will get what you want to happen.
Pretty standard, strings in c++ are null-terminated; characters are not. So by using the standard compare method you're really checking if "b\0" == 'b'.
I used this and got the desired output:
if (my_string.substr(0,1).compare( 0, 1, &my_char2, 1)==0 )
std::cout << "WOW!" << std::endl;
else
std::cout << "NOPE..." << std::endl;
What this is saying is start at position 0 of the substring, use a length of 1, and compare it to my character reference with a length of 1. Reference