Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for
comparing two strings without regard to case. Both for
working with "char*", and with "std::string".
Thanks,
-JKop 28 2215
"JKop" <NU**@NULL.NULL> schrieb im Newsbeitrag
news:ab******************@news.indigo.ie... Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
stricmp(str1, str2);
"JKop" <NU**@NULL.NULL> wrote in message Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
One way is to inherit from char_traits<...> and provide the necessary
overrides. Then use that class instead of std::string. This is discussed in
this GotW series - http://www.gotw.ca/gotw/029.htm
Sharad
"Gernot Frisch" <Me@Privacy.net> wrote in message
news:2q*************@uni-berlin.de... "JKop" <NU**@NULL.NULL> schrieb im Newsbeitrag news:ab******************@news.indigo.ie... Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
stricmp(str1, str2);
stricmp is not standard C or C++.
john
"JKop" <NU**@NULL.NULL> wrote in message
news:ab******************@news.indigo.ie... Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
Thanks,
-JKop
There is no standard C++ function for doing that. You could write something
yourself using the toupper or tolower functions which operate on individual
characters.
john
"Gernot Frisch" <Me@Privacy.net> wrote in message
news:2q*************@uni-berlin.de... "JKop" <NU**@NULL.NULL> schrieb im Newsbeitrag news:ab******************@news.indigo.ie... Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
stricmp(str1, str2);
Isn't that non-standard ?
> stricmp is not standard C or C++.
Uh!? But strcmp is?
"Gernot Frisch" <Me@Privacy.net> wrote in message
news:2q*************@uni-berlin.de... stricmp is not standard C or C++.
Uh!? But strcmp is?
Right.
john
John Harrison posted: "JKop" <NU**@NULL.NULL> wrote in message news:ab******************@news.indigo.ie... Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function
for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
Thanks,
-JKop There is no standard C++ function for doing that. You
could write something yourself using the toupper or tolower functions
which operate on individual characters.
john
Okay not to be too "do stuff for me"ish, but if some-one
has already written such a function, could they please
copy-paste it here, or perhaps post the code for that
"stricmp" function.
Thanks,
-JKop
JKop <NU**@NULL.NULL> writes: Okay not to be too "do stuff for me"ish, but if some-one has already written such a function,
Functions like this have been posted here in the past, based around
lines like
transform(text.begin(),text.end(),text.begin(),tou pper);
"JKop" <NU**@NULL.NULL> skrev i en meddelelse
news:ab******************@news.indigo.ie... Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
Thanks,
-JKop
This is not so simple as it sounds - and this in one of the reasons, there
is no "standard" C++ function of that type.
One difficulty is related to the fact that different countries have
different rules for collation. Sometimes the rules even differ corresponding
to context (is it a dictionary or a telephone book) and sometimes the rules
even differ according to the meaning of the word.
But for an explanation of this, do go to comp.lang.cpp.moderated and search
for recent discussions there (i believe it started in august and lasted
about a month).
Kind regards
Peter
JKop wrote: Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for "char*" and "std::string".
Okay not to be too "do stuff for me"ish, but if some-one has already written such a function, could they please copy-paste it here, or perhaps post the code for that "stricmp" function.
#include <cctype> // for tolower()
#include <cassert>
// returns < 0 if s1 < s2, > 0 if s1 > s2 or 0 if the strings
// are equal (without regard to case)
// ie. behaves like strcmp()
int stricmp(const char *s1, const char *s2)
{
while (*s1 && *s2)
{
if (tolower(*s1++) != tolower(*s2++))
{
return (int) tolower(*s1) - (int) tolower(*s2);
}
}
return (*s1 ? 1 : (*s2 ? -1 : 0));
}
int stricmp(std::string s1, std::string s2)
{
return stricmp(s1.c_str(), s2.c_str());
}
void test_stricmp()
{
assert(stricmp("abc", "abc") == 0);
assert(stricmp("abc", "ABC") == 0);
assert(stricmp("abc", "DEF") < 0);
assert(stricmp("ABC", "def") < 0);
assert(stricmp("DEF", "abc") > 0);
assert(stricmp("def", "ABC") > 0);
assert(stricmp("abc", "abca") < 0);
assert(stricmp("abca", "abc") > 0);
assert(stricmp("", "") == 0);
assert(stricmp("", "a") < 0);
assert(stricmp("a", "") > 0);
}
David Fisher
Sydney, Australia
JKop wrote: Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
Do you want to compare (for collation), or to strictly test for equality?
"David Fisher" <da***@hsa.com.au> wrote in message
news:AK****************@nasal.pacific.net.au... JKop wrote:
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for "char*" and "std::string".
Okay not to be too "do stuff for me"ish, but if some-one has already written such a function, could they please copy-paste it here, or perhaps post the code for that "stricmp" function.
#include <cctype> // for tolower() #include <cassert>
// returns < 0 if s1 < s2, > 0 if s1 > s2 or 0 if the strings // are equal (without regard to case) // ie. behaves like strcmp()
int stricmp(const char *s1, const char *s2) { while (*s1 && *s2) { if (tolower(*s1++) != tolower(*s2++)) { return (int) tolower(*s1) - (int) tolower(*s2); } }
return (*s1 ? 1 : (*s2 ? -1 : 0)); }
int stricmp(std::string s1, std::string s2) { return stricmp(s1.c_str(), s2.c_str()); }
void test_stricmp() { assert(stricmp("abc", "abc") == 0); assert(stricmp("abc", "ABC") == 0); assert(stricmp("abc", "DEF") < 0); assert(stricmp("ABC", "def") < 0); assert(stricmp("DEF", "abc") > 0); assert(stricmp("def", "ABC") > 0); assert(stricmp("abc", "abca") < 0); assert(stricmp("abca", "abc") > 0); assert(stricmp("", "") == 0); assert(stricmp("", "a") < 0); assert(stricmp("a", "") > 0); }
David Fisher Sydney, Australia
It's an error to pass a char to tolower. The valid inputs for tolower are
integers in the range 0 to UCHAR_MAX and EOF. Because chars maybe signed
then passing a char to tolower may result in a negative value being passed
and that has undefined behaviour. Unsigned char is not a problem.
For the same reason
transform(text.begin(),text.end(),text.begin(),tou pper);
suggested by Tim Love is also invalid.
Also this statement
if (tolower(*s1++) != tolower(*s2++))
{
return (int) tolower(*s1) - (int) tolower(*s2);
}
is bugged because s1 and s2 will be incremented in the if statement before
the subtraction is done.
So I'd suggest
int stricmp(const char *s1, const char *s2)
{
while (*s1 && *s2)
{
unsigned char ch1 = *s1;
unsigned char ch2 = *s2;
if (tolower(ch1) != tolower(ch2))
{
return (int)ch1 - (int)ch2;
}
++s1;
++s2;
}
return (*s1 ? 1 : (*s2 ? -1 : 0));
}
but I haven't tested it.
John
John Harrison wrote: It's an error to pass a char to tolower. The valid inputs for tolower are integers in the range 0 to UCHAR_MAX and EOF. Because chars maybe signed then passing a char to tolower may result in a negative value being passed and that has undefined behaviour. Unsigned char is not a problem.
I see your point, but it's very surprising ... most people would expect
something like tolower('A') to return 'a'. I guess it's only a problem
for character sets with upper case characters >= 128 decimal (in ASCII,
upper case letters are from 65 to 90). Are there any character sets
like this you are aware of ? (I don't know EBCDIC).
BTW the UNIX manual entry on my machine says that for any values other
than upper case letters, the argument value is returned unchanged (rather
than being undefined behaviour).
Also this statement
if (tolower(*s1++) != tolower(*s2++)) { return (int) tolower(*s1) - (int) tolower(*s2); }
is bugged because s1 and s2 will be incremented in the if statement before the subtraction is done.
Oops .. of course it was a deliberate mistake ... :-P
Thanks for the comments,
David Fisher
Sydney, Australia
JKop wrote: John Harrison posted:
"JKop" <NU**@NULL.NULL> wrote in message news:ab******************@news.indigo.ie... Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
Thanks,
-JKop
There is no standard C++ function for doing that. You
could write something yourself using the toupper or tolower functions which operate on individual characters.
john
Okay not to be too "do stuff for me"ish, but if some-one has already written such a function, could they please copy-paste it here, or perhaps post the code for that "stricmp" function.
Thanks,
-JKop
Ignoring case is relative to the locale you want to use. The following code
uses the global locale by default:
#include <locale>
#include <string>
#include <iostream>
bool
string_equal_to_ignoring_case ( std::string a,
std::string b,
std::locale loc = std::locale() ) {
if ( a.size() != b.size() ) {
return( false );
}
std::string::size_type length = a.size();
for ( std::string::size_type i = 0;
i < length;
++i ) {
if ( std::tolower( a[i], loc ) != std::tolower( b[i], loc ) ) {
return( false );
}
}
return( true );
}
int main ( void ) {
std::string a ( "Hello World!" );
std::string b ( "hello world!" );
std::cout << string_equal_to_ignoring_case( a, b ) << '\n';
}
Best
Kai-Uwe Bux
"David Fisher" <da***@hsa.com.au> wrote in message
news:S3****************@nasal.pacific.net.au... John Harrison wrote:
It's an error to pass a char to tolower. The valid inputs for tolower are integers in the range 0 to UCHAR_MAX and EOF. Because chars maybe signed then passing a char to tolower may result in a negative value being passed and that has undefined behaviour. Unsigned char is not a problem. I see your point, but it's very surprising ... most people would expect something like tolower('A') to return 'a'.
tolower((unsigned char)'A') will return 'a'.
I guess it's only a problem for character sets with upper case characters >= 128 decimal (in ASCII, upper case letters are from 65 to 90). Are there any character sets like this you are aware of ? (I don't know EBCDIC).
Passing any negative value (other than EOF) to any of the character
classification routines (tolower, islower, isalpha etc) is undefined
behaviour. If you are sure that your 8 bit char string will only ever
contains character codes in the range 0 to 127 then there is no problem. But
you can't be sure of that in a library routine like stricmp. BTW the UNIX manual entry on my machine says that for any values other than upper case letters, the argument value is returned unchanged (rather than being undefined behaviour).
C99 standard 7.4 para 1, 'In all cases [talking about <ctype.h>] the
argument is an int, the value of which shall be representable as an unsigned
char or shall equal the macro EOF'.
But passing a char to ctype.h routines is such a common practise that I
wouldn't be surprised if most compilers accepted negative values and defined
some reasonable behaviour for them.
john
Julie posted: JKop wrote: Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function
for comparing two strings without regard to case. Both for
working with "char*", and with "std::string". Do you want to compare (for collation), or to strictly
test for equality?
Actually, it's for filenames.
kernel32.dll
and
Kernel32.DLL
and
KerNel32.DlL
are the same file!
-JKop tolower((unsigned char)'A') will return 'a'.
(unsigned char)'A' disgusts me!
unsigned char('A')
Also, if you're going for ultimate efficency:
The inputed char:
char k = 'A';
unsigned char& uk = *reinterpret_cast<unsigned char*>(&k);
(I first thought of using a union but the above is better)
-JKop
"JKop" <NU**@NULL.NULL> skrev i en meddelelse
news:8G******************@news.indigo.ie... Julie posted:
JKop wrote: Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
Do you want to compare (for collation), or to strictly test for equality?
Actually, it's for filenames.
kernel32.dll
and
Kernel32.DLL
and
KerNel32.DlL
are the same file!
-JKop
In that case you should compare the same way windows does. I do not know if
Windows compares according to the standard locale on the machine, but my
guess is that they would use some homegrown scheme, where e.g. the danish
letter "ø" compares equal to "Ø" but the german small double s (looks like
the greek beta) is not equal to "SS".
/Peter
In message <AK****************@nasal.pacific.net.au>, David Fisher
<da***@hsa.com.au> writes JKop wrote:
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for "char*" and "std::string".
Okay not to be too "do stuff for me"ish, but if some-one has already written such a function, could they please copy-paste it here, or perhaps post the code for that "stricmp" function.
#include <cctype> // for tolower() #include <cassert>
// returns < 0 if s1 < s2, > 0 if s1 > s2 or 0 if the strings // are equal (without regard to case) // ie. behaves like strcmp()
int stricmp(const char *s1, const char *s2) { while (*s1 && *s2) { if (tolower(*s1++) != tolower(*s2++)) { return (int) tolower(*s1) - (int) tolower(*s2); } }
return (*s1 ? 1 : (*s2 ? -1 : 0)); }
int stricmp(std::string s1, std::string s2) { return stricmp(s1.c_str(), s2.c_str()); }
Won't behave correctly if either of the strings contains embedded '\0',
as comparison will stop at the first one.
--
Richard Herring
On Thu, 16 Sep 2004 08:03:44 GMT, JKop <NU**@NULL.NULL> wrote: char k = 'A';
unsigned char& uk = *reinterpret_cast<unsigned char*>(&k);
Do we have any guarantee that the bit representations are the
same for signed char and unsigned char? What about machines that
use one's complement or BCD?
--
Andre Heinen
My address is "a dot heinen at europeanlink dot com"
One joyful day (Thu, 16 Sep 2004 09:58:35 +1000 to be precise), "David
Fisher" <da***@hsa.com.au> decided that the Usenet community would
benefit from this remarkable comment:
<...> int stricmp(std::string s1, std::string s2) { return stricmp(s1.c_str(), s2.c_str()); }
After many years of doing this myself, this kind of thing now bugs me
intensely. What, you may ask?
Well, I once had a performance issue with a core piece of code I'd
written and ran it through a profiler. To my surprise, way at the top of
the list was the copy constructor for std::string! Replacing this:
int stricmp(std::string s1, std::string s2)
with this:
int stricmp(const std::string &s1, const std::string &s2)
is a whole lot more efficient.
Mark Wright
- ma**@giallo.demon.nl
================Today's Thought====================
"In places where books are burned, one day,
people will be burned" - Heinrich Heine, Germany -
100 years later, Hitler proved him right
================================================== =
Andre Heinen posted: On Thu, 16 Sep 2004 08:03:44 GMT, JKop <NU**@NULL.NULL> wrote: char k = 'A';
unsigned char& uk = *reinterpret_cast<unsigned char*>(&k);
Do we have any guarantee that the bit representations are the same for signed char and unsigned char? What about machines that use one's complement or BCD?
Yes, you're guaranteed that all positive numbers will have the same bit
representation for both signed and unsigned and that's for all the integer
types. (Taking this from my memory, it's there in the standard...
somewhere...).
-JKop
On Thu, 16 Sep 2004 11:10:50 GMT, JKop <NU**@NULL.NULL> wrote: Yes, you're guaranteed that all positive numbers will have the same bit representation for both signed and unsigned and that's for all the integer types. (Taking this from my memory, it's there in the standard... somewhere...).
Actually I was worrying about negative numbers (e.g. ASCII
between 128 and 255).
--
Andre Heinen
My address is "a dot heinen at europeanlink dot com"
JKop wrote: Julie posted:
JKop wrote: Haven't been able to find such a thing.
Can anyone please inform me of a Standard C++ function for comparing two strings without regard to case. Both for working with "char*", and with "std::string".
Do you want to compare (for collation), or to strictly test for equality?
Actually, it's for filenames.
kernel32.dll
and
Kernel32.DLL
and
KerNel32.DlL
are the same file!
-JKop
Then you are better suited using an equality test. I'd suggest reposting under
that premise, and you should get better responses (reason being:
compare/collation includes a lot of unnecessary features that aren't needed for
a simple equality test, and those features aren't simple to resolve in a
platform independent/locale independent way).
On Thursday 16 September 2004 02:52 am, Richard Herring did deign to grace
us with the following: In message <AK****************@nasal.pacific.net.au>, David Fisher <da***@hsa.com.au> writesJKop wrote:
int stricmp(const char *s1, const char *s2) { while (*s1 && *s2) { if (tolower(*s1++) != tolower(*s2++)) { return (int) tolower(*s1) - (int) tolower(*s2); } }
return (*s1 ? 1 : (*s2 ? -1 : 0)); }
int stricmp(std::string s1, std::string s2) { return stricmp(s1.c_str(), s2.c_str()); } Won't behave correctly if either of the strings contains embedded '\0', as comparison will stop at the first one.
When they made the enhancements to C to create C++, did they redefine
the string terminator? I haven't finished the book yet, but I'd have
thought something like that would be kind of important to highlight.
Thanks,
Rich
Rich wrote: int stricmp(std::string s1, std::string s2) { return stricmp(s1.c_str(), s2.c_str()); } Won't behave correctly if either of the strings contains embedded '\0', as comparison will stop at the first one.
When they made the enhancements to C to create C++, did they redefine the string terminator? I haven't finished the book yet, but I'd have thought something like that would be kind of important to highlight.
He was pointing out that a std::string can contain an embedded null
character, and is defined by the string length rather than requiring a
terminator ... the value returned by c_str() has a '\0' at the end, but if
there is an earlier '\0' then the string will seem shorter.
I guess this is important in a library function like stricmp() ... maybe
overkill for other situations ...
David Fisher
Sydney, Australia
In message <xWn3d.6577$464.5753@trnddc01>, Rich Grise <nu**@example.net>
writes On Thursday 16 September 2004 02:52 am, Richard Herring did deign to grace us with the following:
In message <AK****************@nasal.pacific.net.au>, David Fisher <da***@hsa.com.au> writes
[...] int stricmp(std::string s1, std::string s2) { return stricmp(s1.c_str(), s2.c_str()); } Won't behave correctly if either of the strings contains embedded '\0', as comparison will stop at the first one. When they made the enhancements to C to create C++, did they redefine the string terminator? I haven't finished the book yet, but I'd have thought something like that would be kind of important to highlight.
std::string doesn't require a terminator, as it keeps an explicit record
of the length. The only parts of it that have any concept of terminator
are those functions which take a single pointer as argument and expect a
C-style null-terminated char array.
String constants still contain a terminating null, and the str...
functions are unchanged from C.
--
Richard Herring This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: MrCoder |
last post by:
Hey guys, my first post on here so I'll just say "Hello everbody!"
Ok heres my question for you lot.
Is there a faster way to compare 1 byte array to another?
This is my current code
//...
|
by: serge |
last post by:
Is there a stored procedure to allow me to compare two
SQL objects? In my case for example I want to compare
two stored procedures on two different databases?
If there is no SP that does...
|
by: Matt |
last post by:
if (123 > 33) will return true
and
if ("123" > 33) will return true
So my question is, if the above behaviors are the same?? If string is
a number, and
compare with another number, it will...
|
by: tvn007 |
last post by:
#include <iostream>
#include <string>
int main (void){
using namespace std;
string STR =("TEST");
const std::string::size_type STR_SIZE = STR.size();
int count =0;
while ( count <=...
|
by: Einar |
last post by:
Hi,
I wonder if there is a nice bit twiddling hack to compare a large
number of variables?
If you first store them in an array, you can do:
for (i = 0; i < n; i++) {
if (array != value) {...
|
by: raju |
last post by:
hi
can we compare two integers without using relational operators (== != <
<= > >=)
thanks
rajesh s
|
by: David zhu |
last post by:
I've got different result when comparing two strings
using "==" and string.Compare().
The two strings seems to have same value "1202002" in
the quick watch, and both have the same length 7 which I...
|
by: Linda |
last post by:
Hi,
Is there a way to do a "text" (rather than "binary") compareison with
the "like" operator, without changing the global "Option Compare"
setting? I don't want to risk breaking many, many...
|
by: Maric Michaud |
last post by:
Le Friday 05 September 2008 00:14:37 Robert Dailey, vous avez écrit :
This is the normal python way to compare string without case, and the idiomis
not surprising. You''ll often see for loops...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
| |