Need to implement strdup, strnicmp and stricmp

Discussion in 'C Programming' started by jamihuq, Jun 29, 2006.

  1. jamihuq

    jamihuq Guest

    I'm trying to use strdup, strnicmp and stricmp in an OS that doesn't
    have an implementation in the OSs string.h function. Does someone have
    the implementation for these functions and can you please post them.

    Thanks
    Jami
     
    jamihuq, Jun 29, 2006
    #1
    1. Advertising

  2. Roberto Waltman, Jun 29, 2006
    #2
    1. Advertising

  3. jamihuq

    Ian Malone Guest

    jamihuq wrote:
    > I'm trying to use strdup, strnicmp and stricmp in an OS that doesn't
    > have an implementation in the OSs string.h function. Does someone have
    > the implementation for these functions and can you please post them.
    >


    glibc appears to implement strdup, although it shouldn't be taxing to
    write your own. I'll guess from the names the other two are supposed
    to be case independent comparisons. Looping through tolower() first
    then doing a normal strcmp/strncmp would work at a guess (although
    probably slower and needs a duplicating step to do non-destructively
    compared to a locale aware comparison).

    --
    imalone
     
    Ian Malone, Jun 29, 2006
    #3
  4. jamihuq

    pete Guest

    jamihuq wrote:
    >
    > I'm trying to use strdup, strnicmp and stricmp in an OS that doesn't
    > have an implementation in the OSs string.h function. Does someone have
    > the implementation for these functions and can you please post them.


    This is the current form of my case insensitive versions
    of strcmp and strncmp:

    int str_ccmp(const char *s1, const char *s2)
    {
    for (;;) {
    if (*s1 != *s2) {
    int c1 = toupper((unsigned char)*s1);
    int c2 = toupper((unsigned char)*s2);

    if (c2 != c1) {
    return c2 > c1 ? -1 : 1;
    }
    } else {
    if (*s1 == '\0') {
    return 0;
    }
    }
    ++s1;
    ++s2;
    }
    }

    int str_cncmp(const char *s1, const char *s2, size_t n)
    {
    for (;;) {
    if (n-- == 0) {
    return 0;
    }
    if (*s1 != *s2) {
    int c1 = toupper((unsigned char)*s1);
    int c2 = toupper((unsigned char)*s2);

    if (c2 != c1) {
    return c2 > c1 ? -1 : 1;
    }
    } else {
    if (*s1 == '\0') {
    return 0;
    }
    }
    ++s1;
    ++s2;
    }
    }

    --
    pete
     
    pete, Jun 29, 2006
    #4
  5. pete wrote:
    >
    > jamihuq wrote:
    > >
    > > I'm trying to use strdup, strnicmp and stricmp in an OS that doesn't
    > > have an implementation in the OSs string.h function. Does someone have
    > > the implementation for these functions and can you please post them.

    >
    > This is the current form of my case insensitive versions
    > of strcmp and strncmp:

    [...]

    I just ran into a similar situation. The Linux box doesn't have a
    stricmp() function. Rather, it has an identical function called
    strcasecmp().

    #define stricmp(str1,str2) strcasecmp(str1,str2)

    There is probably an equivalent to strnicmp() as well.

    Are either of these functions part of the C standard?

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Jun 29, 2006
    #5
  6. jamihuq

    pete Guest

    Kenneth Brody wrote:

    > The Linux box doesn't have a stricmp() function.
    > Rather, it has an identical function called strcasecmp().
    >
    > #define stricmp(str1,str2) strcasecmp(str1,str2)
    >
    > There is probably an equivalent to strnicmp() as well.
    >
    > Are either of these functions part of the C standard?


    No.

    http://www.open-std.org/JTC1/SC22/WG14/www/docs/

    n869 is very good for function descriptions
    and comes in a text version.

    Some people prefer to use n1124 these days.

    --
    pete
     
    pete, Jun 29, 2006
    #6
  7. Kenneth Brody wrote:
    > pete wrote:
    > >
    > > jamihuq wrote:
    > > >
    > > > I'm trying to use strdup, strnicmp and stricmp in an OS that doesn't
    > > > have an implementation in the OSs string.h function. Does someone have
    > > > the implementation for these functions and can you please post them.

    > >
    > > This is the current form of my case insensitive versions
    > > of strcmp and strncmp:

    > [...]
    >
    > I just ran into a similar situation. The Linux box doesn't have a
    > stricmp() function. Rather, it has an identical function called
    > strcasecmp().
    >
    > #define stricmp(str1,str2) strcasecmp(str1,str2)
    >
    > There is probably an equivalent to strnicmp() as well.
    >
    > Are either of these functions part of the C standard?


    No. strcasecmp is a POSIX extension and stricmp appears to be of
    Microsoft origin. strcasecmp is more likely to be portable although,
    as demonstrated elsethread, it is trivial to write your own version.

    Robert Gamble
     
    Robert Gamble, Jun 29, 2006
    #7
  8. pete wrote:
    > Kenneth Brody wrote:
    >
    > > The Linux box doesn't have a stricmp() function.
    > > Rather, it has an identical function called strcasecmp().
    > >
    > > #define stricmp(str1,str2) strcasecmp(str1,str2)
    > >
    > > There is probably an equivalent to strnicmp() as well.
    > >
    > > Are either of these functions part of the C standard?

    >
    > No.
    >
    > http://www.open-std.org/JTC1/SC22/WG14/www/docs/
    >
    > n869 is very good for function descriptions
    > and comes in a text version.
    >
    > Some people prefer to use n1124 these days.


    Aside from format preferences (txt versus pdf), is there any reason at
    all to prefer n869 over n1124? n1124 contains, for free, the same
    thing you would pay for by purchasing 9899:1999 plus TC1, TC2, and
    other DR corrections all in one document. The reluctance some people
    seem to have over recommending it over n869 puzzles me, is this due
    solely to formatting reasons?

    Robert Gamble
     
    Robert Gamble, Jun 29, 2006
    #8
  9. jamihuq

    Flash Gordon Guest

    Robert Gamble wrote:
    > pete wrote:
    >> Kenneth Brody wrote:
    >>
    >>> The Linux box doesn't have a stricmp() function.
    >>> Rather, it has an identical function called strcasecmp().
    >>>
    >>> #define stricmp(str1,str2) strcasecmp(str1,str2)
    >>>
    >>> There is probably an equivalent to strnicmp() as well.
    >>>
    >>> Are either of these functions part of the C standard?

    >> No.
    >>
    >> http://www.open-std.org/JTC1/SC22/WG14/www/docs/
    >>
    >> n869 is very good for function descriptions
    >> and comes in a text version.
    >>
    >> Some people prefer to use n1124 these days.

    >
    > Aside from format preferences (txt versus pdf), is there any reason at
    > all to prefer n869 over n1124? n1124 contains, for free, the same
    > thing you would pay for by purchasing 9899:1999 plus TC1, TC2, and
    > other DR corrections all in one document. The reluctance some people
    > seem to have over recommending it over n869 puzzles me, is this due
    > solely to formatting reasons?


    Probably the main reason is that most people will be using an
    implementation that can be C89 compliant (possibly with the need of
    appropriate options) but not C99 compliant.
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc
     
    Flash Gordon, Jun 29, 2006
    #9
  10. Flash Gordon wrote:
    > Robert Gamble wrote:
    > > pete wrote:
    > >> Kenneth Brody wrote:
    > >>
    > >>> The Linux box doesn't have a stricmp() function.
    > >>> Rather, it has an identical function called strcasecmp().
    > >>>
    > >>> #define stricmp(str1,str2) strcasecmp(str1,str2)
    > >>>
    > >>> There is probably an equivalent to strnicmp() as well.
    > >>>
    > >>> Are either of these functions part of the C standard?
    > >> No.
    > >>
    > >> http://www.open-std.org/JTC1/SC22/WG14/www/docs/
    > >>
    > >> n869 is very good for function descriptions
    > >> and comes in a text version.
    > >>
    > >> Some people prefer to use n1124 these days.

    > >
    > > Aside from format preferences (txt versus pdf), is there any reason at
    > > all to prefer n869 over n1124? n1124 contains, for free, the same
    > > thing you would pay for by purchasing 9899:1999 plus TC1, TC2, and
    > > other DR corrections all in one document. The reluctance some people
    > > seem to have over recommending it over n869 puzzles me, is this due
    > > solely to formatting reasons?

    >
    > Probably the main reason is that most people will be using an
    > implementation that can be C89 compliant (possibly with the need of
    > appropriate options) but not C99 compliant.


    n869 is the last public C99 draft...

    Robert Gamble
     
    Robert Gamble, Jun 29, 2006
    #10
  11. jamihuq

    Chris Torek Guest

    In article <>
    pete <> wrote:
    >This is the current form of my case insensitive versions
    >of strcmp and strncmp:

    [snippage]
    > int c1 = toupper((unsigned char)*s1);
    > int c2 = toupper((unsigned char)*s2);


    I would convert both to lowercase myself. In German, the eszet
    character (ß -- code point 0xdf -- in ISO Latin 1) is lowercase
    but has no uppercase equivalent (it has to be written as SS). I
    suspect most toupper()s will leave it alone, so the code will
    "work right" anyway; and it is possible there are other languages
    that have an uppercase character with no lowercase equivalent; but
    the existence of this one example is enough for me to favor
    conversion to lowercase.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Jun 29, 2006
    #11
  12. jamihuq

    Eric Sosman Guest

    Chris Torek wrote On 06/29/06 17:52,:
    > In article <>
    > pete <> wrote:
    >
    >>This is the current form of my case insensitive versions
    >>of strcmp and strncmp:

    >
    > [snippage]
    >
    >> int c1 = toupper((unsigned char)*s1);
    >> int c2 = toupper((unsigned char)*s2);

    >
    >
    > I would convert both to lowercase myself. In German, the eszet
    > character (ß -- code point 0xdf -- in ISO Latin 1) is lowercase
    > but has no uppercase equivalent (it has to be written as SS). I
    > suspect most toupper()s will leave it alone, so the code will
    > "work right" anyway; and it is possible there are other languages
    > that have an uppercase character with no lowercase equivalent; but
    > the existence of this one example is enough for me to favor
    > conversion to lowercase.


    The snipped part of the code has already established
    that *s1 != *s2. Things might be different if he were
    doing a wholesale case conversion followed by an ordinary
    strcmp(), but that's not the, er, case.

    --
     
    Eric Sosman, Jun 29, 2006
    #12
  13. jamihuq

    pete Guest

    Robert Gamble wrote:
    >
    > pete wrote:
    > > Kenneth Brody wrote:
    > >
    > > > The Linux box doesn't have a stricmp() function.
    > > > Rather, it has an identical function called strcasecmp().
    > > >
    > > > #define stricmp(str1,str2) strcasecmp(str1,str2)
    > > >
    > > > There is probably an equivalent to strnicmp() as well.
    > > >
    > > > Are either of these functions part of the C standard?

    > >
    > > No.
    > >
    > > http://www.open-std.org/JTC1/SC22/WG14/www/docs/
    > >
    > > n869 is very good for function descriptions
    > > and comes in a text version.
    > >
    > > Some people prefer to use n1124 these days.

    >
    > Aside from format preferences (txt versus pdf), is there any reason at
    > all to prefer n869 over n1124?


    No.

    I quote ISO/IEC 9899:1999 (E), when I have to,
    like for example, when the topic is "negative zero".

    --
    pete
     
    pete, Jun 29, 2006
    #13
  14. jamihuq

    pete Guest

    Chris Torek wrote:
    >
    > In article <>
    > pete <> wrote:
    > >This is the current form of my case insensitive versions
    > >of strcmp and strncmp:

    > [snippage]
    > > int c1 = toupper((unsigned char)*s1);
    > > int c2 = toupper((unsigned char)*s2);

    >
    > I would convert both to lowercase myself. In German, the eszet
    > character (ß -- code point 0xdf -- in ISO Latin 1) is lowercase
    > but has no uppercase equivalent (it has to be written as SS). I
    > suspect most toupper()s will leave it alone, so the code will
    > "work right" anyway; and it is possible there are other languages
    > that have an uppercase character with no lowercase equivalent; but
    > the existence of this one example is enough for me to favor
    > conversion to lowercase.


    The standard says:

    [#3] If the argument is a character for which islower is
    true and there are one or more corresponding characters, as
    specified by the current locale, for which isupper is true,
    the toupper function returns one of the corresponding
    characters (always the same one for any given locale);
    otherwise, the argument is returned unchanged.

    .... which means that toupper returns the eszet argument unchanged.

    I don't understand what are the consequences
    of the worst possible case, that you see.

    --
    pete
     
    pete, Jun 30, 2006
    #14
  15. jamihuq

    SM Ryan Guest

    "jamihuq" <> wrote:
    # I'm trying to use strdup, strnicmp and stricmp in an OS that doesn't
    # have an implementation in the OSs string.h function. Does someone have
    # the implementation for these functions and can you please post them.

    char *strdup(char *s) {
    return strcpy(malloc(strlen(s)+1),s);
    }

    int stricmp(char *s,char *t) {
    int cc;
    do cc = tolower(*s++) - tolower(*t++); while (!cc && s[-1]);
    return cc;
    }

    int strnicmp(char *s,char *t,int n) {
    int cc;
    if (n==0) return 0;
    do cc = tolower(*s++) - tolower(*t++); while (!cc && s[-1] && --n>0);
    return cc;
    }

    --
    SM Ryan http://www.rawbw.com/~wyrmwif/
    We found a loophole; they can't keep us out anymore.
     
    SM Ryan, Jun 30, 2006
    #15
  16. SM Ryan said:

    > "jamihuq" <> wrote:
    > # I'm trying to use strdup, strnicmp and stricmp in an OS that doesn't
    > # have an implementation in the OSs string.h function. Does someone have
    > # the implementation for these functions and can you please post them.
    >
    > char *strdup(char *s) {


    Invasion of implementation namespace. Make s a const char * instead.

    > return strcpy(malloc(strlen(s)+1),s);


    Undefined behaviour if malloc fails.

    > int stricmp(char *s,char *t) {


    Invasion of implementation namespace.

    > int cc;
    > do cc = tolower(*s++) - tolower(*t++); while (!cc && s[-1]);


    Possible underflow issue here if *s is CHAR_MIN and t is positive. Also, the
    negative offset will upset some maintenance programmers. Finally, UB if *s
    or *t is not representable as an unsigned char.

    int cmpistr(const char *s, const char *t)
    {
    unsigned char c, d;
    int diff = 0;
    while(diff == 0 && *s != '\0' && *t != '\0')
    {
    c = *s++;
    d = *t++;
    diff = (c > d) - (c < d);
    }

    if(0 == diff)
    {
    diff = *s ? 1 : -1;
    }

    return diff;
    }

    > int strnicmp(char *s,char *t,int n) {
    > int cc;
    > if (n==0) return 0;
    > do cc = tolower(*s++) - tolower(*t++); while (!cc && s[-1] && --n>0);
    > return cc;


    Much the same comments as above apply here too.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Jun 30, 2006
    #16
  17. jamihuq

    Chris Torek Guest

    >Chris Torek wrote:
    >>I would [use tolower()] myself [on concern for a lowercase character

    that lacks an uppercase equivalent].

    In article <>
    pete <> wrote:
    >The standard says:
    >
    > [#3] If the argument is a character for which islower is
    > true and there are one or more corresponding characters, as
    > specified by the current locale, for which isupper is true,
    > the toupper function returns one of the corresponding
    > characters (always the same one for any given locale);
    > otherwise, the argument is returned unchanged.
    >
    >... which means that toupper returns the eszet argument unchanged.


    My C89 standard is not easily accessible, but I *think* this text
    is new in C99 (or perhaps C95). C89's locale support was not very
    well tacked-down, as I recall.

    Of course, as Eric Sosman pointed out, your original code was
    completely safe anyway.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Jun 30, 2006
    #17
  18. Chris Torek <> writes:
    >>Chris Torek wrote:
    >>>I would [use tolower()] myself [on concern for a lowercase character

    > that lacks an uppercase equivalent].
    >
    > In article <>
    > pete <> wrote:
    >>The standard says:
    >>
    >> [#3] If the argument is a character for which islower is
    >> true and there are one or more corresponding characters, as
    >> specified by the current locale, for which isupper is true,
    >> the toupper function returns one of the corresponding
    >> characters (always the same one for any given locale);
    >> otherwise, the argument is returned unchanged.
    >>
    >>... which means that toupper returns the eszet argument unchanged.

    >
    > My C89 standard is not easily accessible, but I *think* this text
    > is new in C99 (or perhaps C95). C89's locale support was not very
    > well tacked-down, as I recall.


    Here's what C90 says:

    7.3.2.2 The toupper function

    Synopsis
    #include <ctype.h>
    int toupper(int c);

    Description
    The toupper function converts a lowercase letter to the
    corresponding uppercase letter.

    Returns
    If the argument is a character for which islower is true and
    there is a corresponding character for which isupper is true,
    the toupper function returns the corresponding character;
    otherwise, the argument is returned unchanged.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Jun 30, 2006
    #18
  19. jamihuq

    pete Guest

    Chris Torek wrote:
    >
    > >Chris Torek wrote:
    > >>I would [use tolower()] myself [on concern for a lowercase character

    > that lacks an uppercase equivalent].
    >
    > In article <>
    > pete <> wrote:
    > >The standard says:
    > >
    > > [#3] If the argument is a character for which islower is
    > > true and there are one or more corresponding characters, as
    > > specified by the current locale, for which isupper is true,
    > > the toupper function returns one of the corresponding
    > > characters (always the same one for any given locale);
    > > otherwise, the argument is returned unchanged.
    > >
    > >... which means that toupper returns the eszet argument unchanged.

    >
    > My C89 standard is not easily accessible, but I *think* this text
    > is new in C99 (or perhaps C95). C89's locale support was not very
    > well tacked-down, as I recall.


    Well, it doesn't use the word "locale", here:

    ISO/IEC 9899: 1990
    7.3.2.2 The toupper function
    Returns
    If the argument is a character for which islower is true
    and there is a corresponding character for which isupper is true,
    the toupper function returns the corresponding character;
    otherwise, the argument is returned unchanged.

    > Of course, as Eric Sosman pointed out, your original code was
    > completely safe anyway.


    Thank you, to both of you.

    --
    pete
     
    pete, Jun 30, 2006
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JustSomeGuy

    strnicmp in stl string class?

    JustSomeGuy, Sep 21, 2004, in forum: C++
    Replies:
    2
    Views:
    1,832
    David Fisher
    Sep 21, 2004
  2. Bert

    strcmp/strncmp/strnicmp

    Bert, Mar 29, 2005, in forum: C Programming
    Replies:
    1
    Views:
    699
    Richard Bos
    Mar 29, 2005
  3. William  Krick

    comparing two strcasecmp (stricmp) implementations

    William Krick, Nov 10, 2005, in forum: C Programming
    Replies:
    88
    Views:
    2,682
  4. xuatla
    Replies:
    11
    Views:
    764
    Robbie Hatley
    Sep 26, 2005
  5. C. J. Clegg

    Question on strncmp / strnicmp use

    C. J. Clegg, Jan 16, 2009, in forum: C Programming
    Replies:
    56
    Views:
    1,970
    CBFalconer
    Jan 24, 2009
Loading...

Share This Page