Page 1 of 1 [ 10 posts ] 

Roxas_XIII
Veteran
Veteran

User avatar

Joined: 8 Jan 2007
Age: 35
Gender: Male
Posts: 3,217
Location: Laramie, WY

28 Oct 2010, 6:02 pm

Anyone who has done C++ programming, how does one compare two strings while ignoring case? I've searched the MSDN forums again and again for an answer and I got nothing.


_________________
"Yeah, so this one time, I tried playing poker with tarot cards... got a full house, and about four people died." ~ Unknown comedian

Happy New Year from WP's resident fortune-teller! May the cards be ever in your favor.


CloudWalker
Veteran
Veteran

User avatar

Joined: 26 Mar 2009
Age: 36
Gender: Male
Posts: 711

28 Oct 2010, 6:26 pm

It's usually done by converting both strings to upper or lower case before comparison. You mentioned MSDN, if you are using Visual Studio, M$' string object has a ToUpper function. Standard C++'s toupper only works on char, so you need to use it with transform or a loop.



CTBill
Veteran
Veteran

User avatar

Joined: 17 Oct 2008
Age: 61
Gender: Male
Posts: 514
Location: Connecticut, USA

28 Oct 2010, 9:15 pm

If you are using C library functions, look for strcasecmp from string.h. It should be present in most BSD-like distributions.*

C++ library probably has an equivalent member function and/or operators for classed strings, but I can't use C++ library functions and so don't know their particulars.

*Edit: Might also be called stricmp or strcmpi. See http://en.wikipedia.org/wiki/Strcmp



Roxas_XIII
Veteran
Veteran

User avatar

Joined: 8 Jan 2007
Age: 35
Gender: Male
Posts: 3,217
Location: Laramie, WY

31 Oct 2010, 12:21 am

Thanks guys. Actually, I wrote my own standalone function for parsing a string. It does the same thing CloudWalker mentioned about comparing characters using a loop, but it compares the character's ASCII values directly instead of using the function he mentioned. It's not pretty, but it works.


_________________
"Yeah, so this one time, I tried playing poker with tarot cards... got a full house, and about four people died." ~ Unknown comedian

Happy New Year from WP's resident fortune-teller! May the cards be ever in your favor.


Ancalagon
Veteran
Veteran

User avatar

Joined: 25 Dec 2007
Age: 47
Gender: Male
Posts: 2,302

31 Oct 2010, 9:15 am

If it's all ASCII values, there's only one bit difference between upper case and lower case, and it's the sixth bit.

So

char c;
if(isalpha(c))
c &= 0xdf;

should convert everything to uppercase ( use c |= 0x20 to convert to lowercase ).


_________________
"A dead thing can go with the stream, but only a living thing can go against it." --G. K. Chesterton


Roxas_XIII
Veteran
Veteran

User avatar

Joined: 8 Jan 2007
Age: 35
Gender: Male
Posts: 3,217
Location: Laramie, WY

24 Dec 2010, 7:36 pm

Ancalagon wrote:
If it's all ASCII values, there's only one bit difference between upper case and lower case, and it's the sixth bit.

So

char c;
if(isalpha(c))
c &= 0xdf;

should convert everything to uppercase ( use c |= 0x20 to convert to lowercase ).


That's kind of what I was doing, I would add 32 base 10 to convert from lowercase to uppercase and -33 base 10 to convert back.

32 base 10 (decimal) = 0x20 base 16 (hexadecimal) = 0010 0000 base 2 (binary)

likewise, -33 base 10 = 0xdf base 16 = 1101 1111 base 2.

But wouldn't you be subtracting by 32 instead of 33? -32 is actually 1110 0000 base 2, or 0xe0 base 16. See, when you converted 32 to negative you missed a step. Whenever you convert a binary # to it's negation, you have to flip the bits like you did, but then you have to add 1 (0000 0001). It goes like this:

0010 0000 (32)
1101 1111 (binary inverse of 32, actually -33)
+0000 0001 (1)
= 1110 0000 (1 + 1 = 10 in binary, keep the 0 and carry the 1 until you reach the 0 in the sixth bit. That becomes a 1, everything else remains the same)

It's called a two's complement. Basically, it helps when dealing with signed binary values to think of the last bit (in this case, the 8th bit) as a negative. So in the case of an 8 bit signed integer, the bits would have the following values:

-128 64 32 16 8 4 2 1


So whenever you have a negative number, the 8th bit is 1, then for all the other 1 bits, you take the value of the bit and add it to -128. Or, you can simply add the first 7 bits and subract 128.

So, for example, -33, or 1101 1111:

-128 + 64 + 16 + 8 + 4 + 2 + 1 = -64 + 31 = -33

= -128


_________________
"Yeah, so this one time, I tried playing poker with tarot cards... got a full house, and about four people died." ~ Unknown comedian

Happy New Year from WP's resident fortune-teller! May the cards be ever in your favor.


mcg
Veteran
Veteran

User avatar

Joined: 26 Jan 2010
Age: 36
Gender: Male
Posts: 538
Location: Sacramento

25 Dec 2010, 3:30 am

Roxas_XIII wrote:
Ancalagon wrote:
If it's all ASCII values, there's only one bit difference between upper case and lower case, and it's the sixth bit.

So

char c;
if(isalpha(c))
c &= 0xdf;

should convert everything to uppercase ( use c |= 0x20 to convert to lowercase ).


That's kind of what I was doing, I would add 32 base 10 to convert from lowercase to uppercase and -33 base 10 to convert back.

32 base 10 (decimal) = 0x20 base 16 (hexadecimal) = 0010 0000 base 2 (binary)

likewise, -33 base 10 = 0xdf base 16 = 1101 1111 base 2.

But wouldn't you be subtracting by 32 instead of 33? -32 is actually 1110 0000 base 2, or 0xe0 base 16. See, when you converted 32 to negative you missed a step. Whenever you convert a binary # to it's negation, you have to flip the bits like you did, but then you have to add 1 (0000 0001). It goes like this:

0010 0000 (32)
1101 1111 (binary inverse of 32, actually -33)
+0000 0001 (1)
= 1110 0000 (1 + 1 = 10 in binary, keep the 0 and carry the 1 until you reach the 0 in the sixth bit. That becomes a 1, everything else remains the same)

It's called a two's complement. Basically, it helps when dealing with signed binary values to think of the last bit (in this case, the 8th bit) as a negative. So in the case of an 8 bit signed integer, the bits would have the following values:

-128 64 32 16 8 4 2 1


So whenever you have a negative number, the 8th bit is 1, then for all the other 1 bits, you take the value of the bit and add it to -128. Or, you can simply add the first 7 bits and subract 128.

So, for example, -33, or 1101 1111:

-128 + 64 + 16 + 8 + 4 + 2 + 1 = -64 + 31 = -33

= -128
You want to add 32 to convert an uppercase ANSI char to lowercase and subtract 32 to convert a lowercase char to uppercase. Ancalagon's solution with the bitwise operations is better than using addition or subtraction because that way you don't need to check which case the char is to start with. Plus bit twiddling is an essential C skill, so it's good to learn.



Roxas_XIII
Veteran
Veteran

User avatar

Joined: 8 Jan 2007
Age: 35
Gender: Male
Posts: 3,217
Location: Laramie, WY

25 Dec 2010, 3:44 am

I still dont get it. 1101 1111 is -33, not -32. How does that help?


_________________
"Yeah, so this one time, I tried playing poker with tarot cards... got a full house, and about four people died." ~ Unknown comedian

Happy New Year from WP's resident fortune-teller! May the cards be ever in your favor.


mcg
Veteran
Veteran

User avatar

Joined: 26 Jan 2010
Age: 36
Gender: Male
Posts: 538
Location: Sacramento

25 Dec 2010, 12:50 pm

Try this test case:

Code:
char a = 'a';
char b = -33;

cout << (char)(a - 32) << (char)(a & b);

output: AA

You can subtract 32 or do a bitwise and with that bitmask (-33d or 0xDF). You are correct that -33 is the signed decimal representation of that bitmask (0xDF), but you still only want to subtract 32 if you are subtracting rather than taking the bit masking approach.



Roxas_XIII
Veteran
Veteran

User avatar

Joined: 8 Jan 2007
Age: 35
Gender: Male
Posts: 3,217
Location: Laramie, WY

26 Dec 2010, 12:17 am

Huh. Well thanks for the help everyone. Computer geeks helping out computer geeks... such is the way of l33t. :P


_________________
"Yeah, so this one time, I tried playing poker with tarot cards... got a full house, and about four people died." ~ Unknown comedian

Happy New Year from WP's resident fortune-teller! May the cards be ever in your favor.