 |
|
|
 |
|
 |
Unicode builds are pretty much the norm these days. So building in ANSI is totally a thing of the past.
I got to your article by doing a search on my own issue with MFC, and namely when CString::MakeUpper() method wasn't working for non-English Unicode characters. Having found your article I see that the CompareNoCase() method doesn't seem to be working either. "Great!" The question is, what else doesn't work in MFC?
OK, the reason I post this is that I see that you used the actual function that failed in my case to solve the CompareNoCase() issue. So let me tell you that no, your workaround would not work. So whoever has access to a non-English keyboard they can easily do the test. I don't know what to blame here, some locale definition that wasn't set before compiling an MFC project or what.... it really doesn't make any difference, and I don't want to dig into the depths of MFC either. I'm testing it in the out-of-the-box MFC dialog-based template solution for the VS2010. And... it doesn't work.
I did some research myself and found out that a safer alternative would be to either use lstrcmpiW(), or CompareStringW() APIs. There's also an article from a Microsoft fella who details the issue:
http://blogs.msdn.com/b/greggm/archive/2005/09/21/472453.aspx[^]
So you may want to update this article.
|
|
|
|
 |
|
 |
Hi ahmd0,
I'm not sure I completely understand WHY my workaround wouldn't work.
I wrote this article several years ago, so it's definitely possible you are right. But first, I'd like to understand why.
What issue do you have with MakeUpper() that makes you think that my workaround doesn't work?
|
|
|
|
 |
|
 |
ied to use your CompareNocase with MakeUpper, and not works because MakeUpper don't works fine with spanish words. For example:
"código" in spanish is "CÓDIGO" and MakeUpper return "CóDIGO". "Ó" != "ó"
Better with MakeLower?
Yours sincerely
Josemi
|
|
|
|
 |
|
 |
I don't see the problem.
My MyCompareNoCase() method compares the two results of MakeUpper().
So, no matter what the result of MakeUpper() is, it should be twice the same for the same input strings. Right?
So:
* if 1st string = "código" ===> MakeUpper() returns "CóDIGO"
* if 2nd string = "código" ===> MakeUpper() returns "CóDIGO" also. Right?
* So, if you compare the two results of MakeUpper() they are the same.
Then why should MyCompareNoCase() not work?
|
|
|
|
 |
|
 |
Many thanks for your rapid answer
Well. But I want to compare 2 string regardless case = CompareNoCase and if I try to compare:
s1 s2
"código" "código" Ok
"Código" "CÓDIGO" not Ok because s1 = "CóDIGO" and s2 = "CÓDIGO"
Yours sincerely
Josemi
|
|
|
|
 |
|
 |
@ ahmd0,
Thanks for pointing this out. Now I understand what you are saying.
@ Joxemi,
Thanks for helping me understand what can go wrong:
"Código" ==MakeUpper()==> "CóDIGO"
while
"CÓDIGO" ==MakeUpper()==> "CÓDIGO"
So, where you would expect the MyCompareNoCase() method to return zero because "Código" and "CÓDIGO" can be considered equal (ignoring cases), the method doesn't, because MakeUpper() doesn't change the "small" 'ó' into the "big" 'Ó'.
So as ahmd0 pointed out, indeed my workaround method MyCompareNoCase() won't work in those cases.
One remark though:
At the time I wrote this article, in my experience - as you can see on the screenshots - the characters 'é', 'è', 'à', 'â' and 'ç' were all correctly "uppered". There was no 'ó' character in my example string, but it would surprise me a lot if that 'ó' wouldn't have been "uppered" correctly too. Unfortunately, currently it's not easily possible for me to retest that.
There must have been "some setting(s)" that made my MakeUpper() calls work as expected.
However, I have no clue which one(s)...
|
|
|
|
 |
|
|
 |
|
 |
Thanks for letting me know.
It doesn't surprise me, though. Whatever you post somewhere on the internet starts living its own life (and will be copied eventually).
|
|
|
|
 |
|
 |
Thanks a lot!
Serhiy
|
|
|
|
 |
|
 |
It always feels good to see someone else can use something you spent time on.
Thanks for saying thanks
|
|
|
|
 |
|
 |
Thanks ! !!!!
This will appear at the
end of messages you post
to the Code Project
|
|
|
|
 |
|
 |
My friend, take a closer look at the documentation of
CString.CompareNoCase()
strTextUpper.CompareNoCase(strText) returns 0 if they match
so you must use:
if (strTextUpper.CompareNoCase(strText) == 0){
...
}
Lefe is much simpler sometimes
|
|
|
|
 |
|
 |
My friend, take a closer look at the exact code I wrote...
|
|
|
|
 |
|
 |
not affected by locale means it ignores the current locale and will not work for anything except 7 Bit Ascii correctly.
This is a very old problem (pre 1990) with the C library function stricmp.
That is also the reason why stricoll was invented and stricmp never made it to the std C library.
CompareNoCase -> stricmp
CollateNoCase -> stricoll
If you want to have something working that obeys the locale use the Coll* functions or UNICODE
|
|
|
|
 |
|
 |
The code works fine if you compile it in unicode.
=> define UNICODE in your stdafx.h
=> the example should be:
CString strText(_T("élève - à la façon - château")); // French indeed
CString strTextUpper(strText);
strTextUpper.MakeUpper(); // Upper case the original
CString strTextLower(strTextUpper);
strTextLower.MakeLower(); // Lower case the upper cased original
CString strMsg;
if ( strTextUpper.CompareNoCase(strText) )
strMsg.Format(_T("Original text: <%s>\n")
_T("Uppered: <%s>\n")
_T("CompareNoCase says they differ!\n")
_T("Lowered again: <%s>\n\n")
_T("Conclusion: CompareNoCase doesn't work correctly!"),
strText, strTextUpper, strTextLower);
else
strMsg.Format(_T("Original:%s\nUppered:%s\nLowered again:%s\n\n")
_T("Conclusion: CompareNoCase works as expected!"),
strText, strTextUpper, strTextLower);
AfxMessageBox(strMsg);
Lionel Schiepers
Bureau van Dijk Electronic Publishing
http://www.bvdep.com/
Av. Louise, 250 B14
B1050 Brussels
Belgium
|
|
|
|
 |
|
 |
This is correct. I ran into a similar problem while coding for an Italian customer. The English version worked great, but when we compiled it in Italian, all sorts of things happened. When I turned on UNICODE, however, everything went back to normal. If you are writing code that won't be used on a Windows 9x machine, I would always turn on UNICODE to be safe.
Zac
"If I create everything new, why would I want to delete anything?"
|
|
|
|
 |
|
 |
But if use UNICODE those characters -"éàçâ" aren't converted to uppercase.
Crystal.
|
|
|
|
 |
|
 |
Even using Unicode, sorting will not be correct. I have yet to find a solution:
Input: Ça - Cabale - Zéro
Output: Cabale - Zéro - Ça
instead of Cabale - Ça - Zéro
|
|
|
|
 |
|
 |
I think it would be a better solution to use setlocale().
This way it is easy to use CompareNoCase() instead of MyCompareNoCase() which
could end up in bugs beeing shipped.
(and problably will)
|
|
|
|
 |
|
 |
Well,
my experience is that using CompareNoCase() led to bugs in the field, so I have more confidence in my own MyCompareNoCase() wat really does what it should.
But maybe that's a matter of taste.
|
|
|
|
 |
|
 |
Another thing is that there are other clib function that is affected by setlocale() and you are only patching one of them.
|
|
|
|
 |
|
 |
Well, We (as eurpeans) have to do so difficult...
LPCSTR Dutch = "Double Dutch "
|
|
|
|
 |
|
|
 |
|
 |
This is a blasted bug for sure!
I won't face this problem cause I always develop for American clients and I wouldn't have to use fancy characters.
But if I ever do, then this might have hit me too!
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
 |