Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > comparing two strcasecmp (stricmp) implementations

Reply
Thread Tools

comparing two strcasecmp (stricmp) implementations

 
 
William Krick
Guest
Posts: n/a
 
      11-10-2005
I'm currently evaluating two implementations of a case insensitive
string comparison function to replace the non-ANSI stricmp(). Both of
the implementations below seem to work fine but I'm wondering if one is
better than the other or if there is some sort of hybrid of the two
that would be superior.


IMPLEMENTATION 1:

#ifndef HAVE_STRCASECMP
#define ccmp(a,b) ((a) == (b) ? 0 : ((a) > (b) ? 1 : -1))
int strcasecmp(unsigned char *s1, unsigned char *s2)
{
unsigned char c1, c2;
for ( ; ; )
{
if (*s1 == '\0' || *s2 == '\0')
return ccmp(*s1,*s2);
c1= (isascii(*s1) && isupper(*s1)) ? (unsigned char) tolower(*s1) :
*s1;
c2= (isascii(*s2) && isupper(*s2)) ? (unsigned char) tolower(*s2) :
*s2;
if (c1 != c2)
return ccmp(c1,c2);
s1++;
s2++;
}
}
#undef ccmp
#endif


IMPLEMENTATION 2:

int strcasecmp(const char *s1, const char *s2)
{
unsigned char c1,c2;
do {
c1 = *s1++;
c2 = *s2++;
c1 = (unsigned char) tolower( (unsigned char) c1);
c2 = (unsigned char) tolower( (unsigned char) c2);
}
while((c1 == c2) && (c1 != '\0'));
return (int) c1-c2;
}

 
Reply With Quote
 
 
 
 
Chris Dollin
Guest
Posts: n/a
 
      11-10-2005
William Krick wrote:

> I'm currently evaluating two implementations of a case insensitive
> string comparison function to replace the non-ANSI stricmp(). Both of
> the implementations below seem to work fine but I'm wondering if one is
> better than the other or if there is some sort of hybrid of the two
> that would be superior.
>
>
> IMPLEMENTATION 1:
>
> #ifndef HAVE_STRCASECMP
> #define ccmp(a,b) ((a) == (b) ? 0 : ((a) > (b) ? 1 : -1))
> int strcasecmp(unsigned char *s1, unsigned char *s2)
> {
> unsigned char c1, c2;
> for ( ; ; )
> {
> if (*s1 == '\0' || *s2 == '\0')
> return ccmp(*s1,*s2);
> c1= (isascii(*s1) && isupper(*s1)) ? (unsigned char) tolower(*s1) :
> *s1;
> c2= (isascii(*s2) && isupper(*s2)) ? (unsigned char) tolower(*s2) :
> *s2;
> if (c1 != c2)
> return ccmp(c1,c2);
> s1++;
> s2++;
> }
> }
> #undef ccmp
> #endif
>
>
> IMPLEMENTATION 2:
>
> int strcasecmp(const char *s1, const char *s2)
> {
> unsigned char c1,c2;
> do {
> c1 = *s1++;
> c2 = *s2++;
> c1 = (unsigned char) tolower( (unsigned char) c1);
> c2 = (unsigned char) tolower( (unsigned char) c2);
> }
> while((c1 == c2) && (c1 != '\0'));
> return (int) c1-c2;
> }


How about:

int strcasecmp( const char *s1, const char *s2 )
{
while (1)
{
int c1 = tolower( (unsigned char) *s1++ );
int c2 = tolower( (unsigned char) *s2++ );
if (c1 == 0 || c1 != c2) return c1 - c2;
}
}

Doesn't reuse variables, doesn't have iffy casts, slightly shorter.
What have I missed?

--
Chris "one-track" Dollin
Capability does not imply necessity.
 
Reply With Quote
 
 
 
 
William Krick
Guest
Posts: n/a
 
      11-10-2005
To make the code compatible with older C compilers, I had to move the
declaration of c1 & c2 up to the top. I also changed it from while(1)
to for(; because the while was throwing a warning. However, while
this code works great in most cases, it doesn't handle NULL strings and
just blows up.

int strcasecmp( const char *s1, const char *s2 )
{
int c1, c2;
for(;
{
c1 = tolower( (unsigned char) *s1++ );
c2 = tolower( (unsigned char) *s2++ );
if (c1 == 0 || c1 != c2)
return c1 - c2;
}
}

 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      11-10-2005
In article < .com>,
William Krick <> wrote:

>To make the code compatible with older C compilers, I had to move the
>declaration of c1 & c2 up to the top.


Really? What C compilers are these?

>I also changed it from while(1)
>to for(; because the while was throwing a warning.


Definitely time for a new compiler!

>However, while
>this code works great in most cases, it doesn't handle NULL strings and
>just blows up.


Since when were the str* functions supposed to handle NULL?

-- Richard
 
Reply With Quote
 
Chris Dollin
Guest
Posts: n/a
 
      11-10-2005
William Krick wrote:

> To make the code compatible with older C compilers, I had to move the
> declaration of c1 & c2 up to the top.


You're not serious, surely. You have C compilers that don't allow
declarations in nested blocks? This is not a recent feature.

> I also changed it from while(1)
> to for(; because the while was throwing a warning.


Well, OK I suppose; but I'd be deeply suspicious of such a warning
myself (perhaps I used while(1) more than usual).

> However, while
> this code works great in most cases, it doesn't handle NULL strings and
> just blows up.


There are no such things as NULL strings. There are null (empty) strings,
and there are null pointers, which are not any kind of string. If you mean
that it doesn't handle null pointer arguments, well no, it doesn't; it
does case-insensitive string compare, and NULL isn't a string. The user
should not call it with null pointer arguments.

(I can't think of a sensible answer to return for any null argument. If
you really really want to guard for this case, just add to the top

if (s1 == 0 || s2 == 0) return WHATEVERYOUWANT;

or wrap it as

if (s1 && s2) THEPREVIOUSCODE
else return WHATEVERYOUWANT;
)

> int strcasecmp( const char *s1, const char *s2 )
> {
> int c1, c2;
> for(;
> {
> c1 = tolower( (unsigned char) *s1++ );
> c2 = tolower( (unsigned char) *s2++ );
> if (c1 == 0 || c1 != c2)
> return c1 - c2;
> }
> }


--
Chris "one-track" Dollin
Capability does not imply necessity.
 
Reply With Quote
 
William Krick
Guest
Posts: n/a
 
      11-10-2005

Chris Dollin wrote:
> William Krick wrote:
>
> > However, while
> > this code works great in most cases, it doesn't handle NULL strings and
> > just blows up.

>
> There are no such things as NULL strings. There are null (empty) strings,
> and there are null pointers, which are not any kind of string. If you mean
> that it doesn't handle null pointer arguments, well no, it doesn't; it
> does case-insensitive string compare, and NULL isn't a string. The user
> should not call it with null pointer arguments.



Point taken. This is my first foray back into C after being a Java
programmer for 5 years. I admit I'm VERY rusty.

I think Richard Tobin was right when he said...
"Since when were the str* functions supposed to handle NULL?"

I shouldn't be trying to handle null pointers.

Thanks for your help everyone.

 
Reply With Quote
 
Skarmander
Guest
Posts: n/a
 
      11-10-2005
Chris Dollin wrote:
> William Krick wrote:

<snip>
>>However, while
>>this code works great in most cases, it doesn't handle NULL strings and
>>just blows up.

>
>
> There are no such things as NULL strings. There are null (empty) strings,
> and there are null pointers, which are not any kind of string. If you mean
> that it doesn't handle null pointer arguments, well no, it doesn't; it
> does case-insensitive string compare, and NULL isn't a string. The user
> should not call it with null pointer arguments.
>
> (I can't think of a sensible answer to return for any null argument. If
> you really really want to guard for this case, just add to the top
>
> if (s1 == 0 || s2 == 0) return WHATEVERYOUWANT;
>

I'd prefer

assert(s1 && s2);

Or a (documented) redefinition of the semantics (e.g., treat 0 as "").

You could use WHATEVERYOUWANT if you document either it or the fact that
passing null pointers will yield an indeterminate value. Don't keep it
under the hood, in any case.

S.
 
Reply With Quote
 
Alan Balmer
Guest
Posts: n/a
 
      11-10-2005
On Thu, 10 Nov 2005 17:27:47 +0000, Chris Dollin <>
wrote:

>> I also changed it from while(1)
>> to for(; because the while was throwing a warning.

>
>Well, OK I suppose; but I'd be deeply suspicious of such a warning
>myself (perhaps I used while(1) more than usual).


In my experience, this warning is quite common. The warning is that
the condition is always true. In more complex cases, it can be useful.

I seem to remember that we had a fairly lengthy thread about this not
long ago. Might have been a different NG.
--
Al Balmer
Balmer Consulting

 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      11-10-2005
William Krick wrote:
>
> I'm currently evaluating two implementations of a case insensitive
> string comparison function to replace the non-ANSI stricmp().
> Both of
> the implementations below seem to work fine
> but I'm wondering if one is
> better than the other or if there is some sort of hybrid of the two
> that would be superior.


This is what I use:

int str_ccmp(const char *s1, const char *s2)
{
const unsigned char *p1 = (const unsigned char *)s1;
const unsigned char *p2 = (const unsigned char *)s2;

while (toupper(*p1) == toupper(*p2)) {
if (*p1 == '\0') {
return 0;
}
++p1;
++p2;
}
return toupper(*p2) > toupper(*p1) ? -1 : 1;
}

--
pete
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      11-10-2005


pete wrote On 11/10/05 12:58,:
> William Krick wrote:
>
>>I'm currently evaluating two implementations of a case insensitive
>>string comparison function to replace the non-ANSI stricmp().
>> Both of
>>the implementations below seem to work fine
>>but I'm wondering if one is
>>better than the other or if there is some sort of hybrid of the two
>>that would be superior.

>
>
> This is what I use:
>
> int str_ccmp(const char *s1, const char *s2)
> {
> const unsigned char *p1 = (const unsigned char *)s1;
> const unsigned char *p2 = (const unsigned char *)s2;


These would be incorrect (or at the very least dubious)
on signed-magnitude or ones' complement machines. In the
Immortal Words (which someone reacently mis-attributed to
me; they're by Henry Spencer): "If you lie to the compiler,
it will have its revenge." The above are lies, so ...

--


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Two different `architecture' implementations? Merciadri Luca VHDL 4 11-02-2010 08:21 PM
stricmp() versus strcasecmp( ahso C++ 4 11-25-2009 03:29 PM
Two implementations of simple math equation yield different results Avi C++ 6 05-14-2008 08:04 AM
How to compare two SOAP Envelope or two Document or two XML files GenxLogic Java 3 12-06-2006 08:41 PM
Comparing two textboxes Steffen Loringer ASP .Net 1 04-26-2004 09:55 AM



Advertisments
 



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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57