Is there a better way to do this?

M

mike3

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?
 
A

Ark Khasin

mike3 said:
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
 
B

Ben Pfaff

mike3 said:
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;
 
M

mike3

mike3 said:
I did this in a C program, which involves searching for the occurence
of a string
in another string:
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.
 
M

mike3

mike3 said:
I did this in a C program, which involves searching for the
occurence of a string in another string:
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.
 
A

Ark Khasin

mike3 said:
mike3 said:
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
 
A

Army1987

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...)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top