Is there a better way to do this?

Discussion in 'C Programming' started by mike3, Sep 21, 2007.

  1. mike3

    mike3 Guest

    Hi.

    I did this in a C program, which involves searching for the occurence
    of a string
    in another string:

    ---
    posptr = strstr(MyString, StringToFind);

    if(posptr == NULL) return(-1); /* Didn't find it */
    return(((int)(StringToFind - &MyString[0]))/sizeof(char)); /* turn
    returned pointer into a zero-indexed character offset */
    ---

    ("MyString" and "StringToFind" are both arrays of type char and null-
    terminated.)

    It's that last part I'm wondering about. Is that part "legal" in
    standard C? Safe?
    If not, what's a more "legal" or "safe" method to accomplish what I'm
    trying
    to accomplish with this?
     
    mike3, Sep 21, 2007
    #1
    1. Advertising

  2. mike3

    Ark Khasin Guest

    mike3 wrote:
    > Hi.
    >
    > I did this in a C program, which involves searching for the occurence
    > of a string
    > in another string:
    >
    > ---
    > posptr = strstr(MyString, StringToFind);
    >
    > if(posptr == NULL) return(-1); /* Didn't find it */
    > return(((int)(StringToFind - &MyString[0]))/sizeof(char)); /* turn
    > returned pointer into a zero-indexed character offset */
    > ---
    >
    > ("MyString" and "StringToFind" are both arrays of type char and null-
    > terminated.)
    >
    > It's that last part I'm wondering about. Is that part "legal" in
    > standard C? Safe?
    > If not, what's a more "legal" or "safe" method to accomplish what I'm
    > trying
    > to accomplish with this?
    >

    1. /sizeof(char) is redundant since sizeof(char)==1. However, you may
    want to keep it your way if it adds to clarity.
    2. StringToFind - &MyString[0] is illegal (pointers NOT to the same
    array); you may have meant
    posptr - &MyString[0]
    which is the same as
    posptr - MyString
    and is of type ptrdiff_t which may be wider than int. How about this:
    ptrdiff_t ret = posptr - MyString;
    assert(ret == (int)ret);
    return (int)ret;
    -- Ark
     
    Ark Khasin, Sep 21, 2007
    #2
    1. Advertising

  3. mike3

    Ben Pfaff Guest

    mike3 <> writes:

    > I did this in a C program, which involves searching for the
    > occurence of a string in another string:
    >
    > ---
    > posptr = strstr(MyString, StringToFind);
    >
    > if(posptr == NULL) return(-1); /* Didn't find it */
    > return(((int)(StringToFind - &MyString[0]))/sizeof(char)); /* turn
    > returned pointer into a zero-indexed character offset */


    Several comments on that last statement:

    * Most importantly, StringToFind and &MyString[0] do not
    point within the same array, so the result of the
    subtraction is undefined. Fortunately, it seems that
    you really just made a small mistake here: I think that
    you really want to subtract &MyString[0] from posptr,
    not from StringToFind.

    * &MyString[0] and MyString have the same type and value,
    except in a few specific contexts, and so you might as
    well write the latter.

    * The cast to int is gratuitous. The result of
    subtracting one pointer from another is already a
    signed integer type (often int). Casting this result
    to int will either have no effect on its value (the
    common case) or yield undefined behavior (if the result
    is out of the range of int), so there's no point in
    doing it.

    * Division by sizeof(char) is also gratuitous, because
    sizeof(char) is always 1 by definition.

    Thus, you can correctly write this statement as simply:
    return posptr - MyString;
    --
    char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
    =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
    2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
     
    Ben Pfaff, Sep 21, 2007
    #3
  4. mike3

    mike3 Guest

    On Sep 20, 9:10 pm, Ark Khasin <> wrote:
    > mike3 wrote:
    > > Hi.

    >
    > > I did this in a C program, which involves searching for the occurence
    > > of a string
    > > in another string:

    >
    > > ---
    > > posptr = strstr(MyString, StringToFind);

    >
    > > if(posptr == NULL) return(-1); /* Didn't find it */
    > > return(((int)(StringToFind - &MyString[0]))/sizeof(char)); /* turn
    > > returned pointer into a zero-indexed character offset */
    > > ---

    >
    > > ("MyString" and "StringToFind" are both arrays of type char and null-
    > > terminated.)

    >
    > > It's that last part I'm wondering about. Is that part "legal" in
    > > standard C? Safe?
    > > If not, what's a more "legal" or "safe" method to accomplish what I'm
    > > trying
    > > to accomplish with this?

    >
    > 1. /sizeof(char) is redundant since sizeof(char)==1. However, you may
    > want to keep it your way if it adds to clarity.
    > 2. StringToFind - &MyString[0] is illegal (pointers NOT to the same
    > array); you may have meant
    > posptr - &MyString[0]


    Sorry, yes that is what I meant.

    > which is the same as
    > posptr - MyString
    > and is of type ptrdiff_t which may be wider than int. How about this:
    > ptrdiff_t ret = posptr - MyString;
    > assert(ret == (int)ret);
    > return (int)ret;


    Alright.

    > -- Ark
     
    mike3, Sep 21, 2007
    #4
  5. mike3

    mike3 Guest

    On Sep 20, 9:14 pm, Ben Pfaff <> wrote:
    > mike3 <> writes:
    > > I did this in a C program, which involves searching for the
    > > occurence of a string in another string:

    >
    > > ---
    > > posptr = strstr(MyString, StringToFind);

    >
    > > if(posptr == NULL) return(-1); /* Didn't find it */
    > > return(((int)(StringToFind - &MyString[0]))/sizeof(char)); /* turn
    > > returned pointer into a zero-indexed character offset */

    >
    > Several comments on that last statement:
    >
    > * Most importantly, StringToFind and &MyString[0] do not
    > point within the same array, so the result of the
    > subtraction is undefined. Fortunately, it seems that
    > you really just made a small mistake here: I think that
    > you really want to subtract &MyString[0] from posptr,
    > not from StringToFind.
    >
    > * &MyString[0] and MyString have the same type and value,
    > except in a few specific contexts, and so you might as
    > well write the latter.
    >
    > * The cast to int is gratuitous. The result of
    > subtracting one pointer from another is already a
    > signed integer type (often int). Casting this result
    > to int will either have no effect on its value (the
    > common case) or yield undefined behavior (if the result
    > is out of the range of int), so there's no point in
    > doing it.
    >
    > * Division by sizeof(char) is also gratuitous, because
    > sizeof(char) is always 1 by definition.
    >
    > Thus, you can correctly write this statement as simply:
    > return posptr - MyString;
    > --
    > char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    > ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
    > =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
    > 2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}


    Thanks for the response. I'll do that.
     
    mike3, Sep 21, 2007
    #5
  6. mike3

    Ark Khasin Guest

    mike3 wrote:
    > On Sep 20, 9:10 pm, Ark Khasin <> wrote:
    >> mike3 wrote:
    >>> Hi.
    >>> I did this in a C program, which involves searching for the occurence
    >>> of a string
    >>> in another string:
    >>> ---
    >>> posptr = strstr(MyString, StringToFind);
    >>> if(posptr == NULL) return(-1); /* Didn't find it */
    >>> return(((int)(StringToFind - &MyString[0]))/sizeof(char)); /* turn
    >>> returned pointer into a zero-indexed character offset */
    >>> ---
    >>> ("MyString" and "StringToFind" are both arrays of type char and null-
    >>> terminated.)
    >>> It's that last part I'm wondering about. Is that part "legal" in
    >>> standard C? Safe?
    >>> If not, what's a more "legal" or "safe" method to accomplish what I'm
    >>> trying
    >>> to accomplish with this?

    >> 1. /sizeof(char) is redundant since sizeof(char)==1. However, you may
    >> want to keep it your way if it adds to clarity.
    >> 2. StringToFind - &MyString[0] is illegal (pointers NOT to the same
    >> array); you may have meant
    >> posptr - &MyString[0]

    >
    > Sorry, yes that is what I meant.
    >
    >> which is the same as
    >> posptr - MyString
    >> and is of type ptrdiff_t which may be wider than int. How about this:
    >> ptrdiff_t ret = posptr - MyString;
    >> assert(ret == (int)ret);
    >> return (int)ret;

    >
    > Alright.
    >
    >> -- Ark

    >
    >

    On a second thought, /sizeof(char) is plainly misleading, rather than
    "redundant" or "gratuitous": a difference of two pointers is already
    scaled to the size of the objects pointed to.
    e.g,
    T foo[];
    &foo[5]-&foo[0] == 5
    whatever the type T is.
    -- Ark
     
    Ark Khasin, Sep 21, 2007
    #6
  7. mike3

    Army1987 Guest

    On Fri, 21 Sep 2007 03:10:25 +0000, Ark Khasin wrote:

    > mike3 wrote:
    > ptrdiff_t ret = posptr - MyString;
    > assert(ret == (int)ret);

    I think assert(ret <= INT_MAX) is clearer. (Also I don't think it is
    the case to use assert() here...)
    --
    Army1987 (Replace "NOSPAM" with "email")
    If you're sending e-mail from a Windows machine, turn off Microsoft's
    stupid “Smart Quotes†feature. This is so you'll avoid sprinkling garbage
    characters through your mail. -- Eric S. Raymond and Rick Moen
     
    Army1987, Sep 21, 2007
    #7
    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. dwa

    There MUST be a better way!

    dwa, Jan 28, 2004, in forum: ASP .Net
    Replies:
    5
    Views:
    429
    Marauderz
    Jan 29, 2004
  2. Guadala Harry

    Nested DIVs - is there a better way?

    Guadala Harry, Oct 26, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    489
    Guadala Harry
    Oct 26, 2004
  3. Peter Bencsik
    Replies:
    2
    Views:
    839
  4. Paul Rubin
    Replies:
    5
    Views:
    419
    Hendrik van Rooyen
    Aug 6, 2009
  5. Replies:
    2
    Views:
    56
    Mark H Harris
    May 13, 2014
Loading...

Share This Page