Comparing two strings program?

Hello!

Ok so basically I am learning C++ from a self teach book and I have come across a program I am a little confused about in certain areas; my book asked me to "Write a program that prompts the user for two strings and then compares the strings for equality, but ignores case differences.".

I will post the whole program below if you need it.

So the area which I don't understand is the while loop and the code that goes on inside it, mean I know how a if statement works and what the "++" does.
1
2
3
4
5
6
7
while(*p1 && *p2) {
		if(tolower(*p1) != tolower(*p2)) break;
		else {
			p1++;
			p2++;
		}
	}


I just don't understand how and why this area of code works; what does the p1++ do? Plus does tolower() return back a lower case value?


Also, what does the '!' mark mean in this if statement does that mean not equal, if so why isn't the '!=' used here: if(!*p1 && !*p2)

Thank you, Luke

P.S I'm very new to C++.

Whole program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <cstring>
using namespace std;

int main() {
	char str1[80];
	char str2 [80];
	char *p1, *p2;

	cout << "Enter the first string: ";
	cin >> str1;
	cout << "Enter the second string: ";
	cin >> str2;

	p1 = str1;
	p2 = str2;

	while(*p1 && *p2) {
		if(tolower(*p1) != tolower(*p2)) break;
		else {
			p1++;
			p2++;
		}
	}

	if(!*p1 && !*p2)

		cout << "String are the same except for " << "possible case differences.\n";
	else cout << "Strings differ.";

	cout << "\n\n";

	return 0;

}


1
2
3
4
5
6
7
8
9
10
while(*p1 && *p2) 
{
	if(tolower(*p1) != tolower(*p2)) 
		break;
	else 
	{
		p1++;
		p2++;
	}
}


What this is doing is:
1
2
3
4
5
6
7
8
while ( this element in p1 is not zero, AND, this element in p2 is not zero) then
    if (this element of p1 is equal to this element of p2) then
        exit the loop
    else
        p1 becomes the next element in p1.
        p2 becomes the next element in p2.
    end if
end while


oh, and
1
2
p1++;
p1 = p1 + 1;
Last edited on
By the way this loop

1
2
3
4
5
6
7
while(*p1 && *p2) {
		if(tolower(*p1) != tolower(*p2)) break;
		else {
			p1++;
			p2++;
		}
	}


could be written simpler

while ( *p1 && tolower( *p1 ) == tolower( *p2 ) ) ++p1, ++p2;
tolower() returns the lower case character yes.
http://www.cplusplus.com/reference/cctype/tolower/
as for p1++ I am guessing that is either a pointer to a char array or an iterator of a string. It is probably starting at the first character then when you increment it , it points to the next character. So basically what it is doing is looping through the strings and checking each character (as a lower case) to the second one.
basically if you have CAR car it will check if c == c ,a == a , r == r.

! means not so when you do something like that you are saying not true aka false.
You could technically write
if( *p1 != true && *p2 != true );
and for your while statement while( *p1 == true && *p2 == true );

*edit looks like the others beat me to it =p I guess I took too long typing


Another way you could write your program using strings instead of char arrays would be like this ps where I have the iterator std::string::iterator you could put the keyword auto instead but I wont so it's easier to understand.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <string>

int main()
{
    std::string s_input_one( "" ) , s_input_two( "" );

    std::cout << "Please enter a string: " << std::endl;
    std::getline( std::cin , s_input_one ); //I like getline for strings
    std::cout << "Please enter a string: " << std::endl;
    std::getline( std::cin , s_input_two ); //You could make these into sub functions if you wanted I guess but I can't be bothered for something this simple

    std::string::iterator s_it_one( s_input_one.begin() ) , s_it_two( s_input_two.begin() );

    while( *s_it_one && tolower(*s_it_one) == tolower(*s_it_two) )
    {
        ++s_it_one;
        ++s_it_two;
    }

    if( s_it_one == s_input_one.end() && !*s_it_two ) //thse are same two statements
    {
        std::cout << "The strings are the same with possible case differences" << std::endl;
    }
    else
    {
         std::cout << "The strings are different" << std::endl;
    }

    return( 0 );
}


*edit
I also think you should check to see if the size of the strings are the same..If they are not the same size they are obv different.
Last edited on
One more thing to mention you can use the compare
http://www.cplusplus.com/reference/string/string/compare/

or operator== if they are case sensitive
[code]
string1 == string 2...
[code]
@giblit



1
2
3
4
5
    while( *s_it_one && tolower(*s_it_one) == tolower(*s_it_two) )
    {
        ++s_it_one;
        ++s_it_two;
    }


This code is invalid because you are dereferencing iterators that can be equal to end().
fine..
while( s_it_one != s_input_one.end() && tolower(*s_it_one) == tolower(*s_it_two) )
@giblit

fine..
while( s_it_one != s_input_one.end() && tolower(*s_it_one) == tolower(*s_it_two) )



This statement is also invalid because it does not orevent from dereferencing iterator s_it_two that can be equal to end():)
Thanks guys!

You really helped me out, I understand it now.

Just want to say thanks as everyone I've spoke to on here has been really helpful.

@giblet
@vlad from Moscow
@Stewbond


Your all great!
Topic archived. No new replies allowed.