Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

CsRookie

macrumors newbie
Original poster
Apr 13, 2011
17
0
Code:
int  findString (const char  source[], const char  s[])
{
    int  i, j, foundit = false;

    // try each character in source 

    for ( i = 0;  source[i] != '\0'  &&  !foundit;  ++i ) {
        foundit = true;

        // now see if corresponding chars from s match 

        for ( j = 0;  s[j] != '\0' &&  foundit;  ++j )
            if ( source[j + i] != s[j] || source[j + i] == '\0' )
              foundit = false;

        if (foundit)
           return i;
    }

    return -1;
}


How would I go about using pointers in this function rather than array notation? Kind of confused on the pointers and their uses. Thanks in advance for the help. :apple:
 

subsonix

macrumors 68040
Feb 2, 2008
3,551
79
So what is the function suppose to do? Find the sub-string s in source and return the index in source if found? In any case, if you intend to manipulate the pointers directly in the function you cannot declare them as const.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
The following 2 declarations are equivalent, the array notation in a parameter list just expresses an expectation that the pointer is an array, and not just a pointer to a single value.

Code:
int  findString (const char  source[], const char  s[]);
int  findString (const char  *source, const char  *s);

The following two sets of statements are equivalent, where the first line is equivalent to the second line.
Code:
char c = s[i];
char c = *(s + i);
Code:
s[i] = 'a';
*(s + i) = 'a';
 

subsonix

macrumors 68040
Feb 2, 2008
3,551
79
That is true, but if the choice lays between, s and *(s + i), why not use the more clear: s?

If you want to do this with the pointers directly, do it without an index. That is my suggestion at least.
 

CsRookie

macrumors newbie
Original poster
Apr 13, 2011
17
0
The following 2 declarations are equivalent, the array notation in a parameter list just expresses an expectation that the pointer is an array, and not just a pointer to a single value.

Code:
int  findString (const char  source[], const char  s[]);
int  findString (const char  *source, const char  *s);

The following two sets of statements are equivalent, where the first line is equivalent to the second line.
Code:
char c = s[i];
char c = *(s + i);
Code:
s[i] = 'a';
*(s + i) = 'a';

Thank you very much for the help :apple:
 

CsRookie

macrumors newbie
Original poster
Apr 13, 2011
17
0
That is true, but if the choice lays between, s and *(s + i), why not use the more clear: s?

If you want to do this with the pointers directly, do it without an index. That is my suggestion at least.




Code:
int main()
{

    //find
    printf("Found at %i\n", findString("chatterbox", "hat"));
    printf("Found at %i\n", findString("chatterbox", "att"));
    printf("Found at %i\n", findString("chatterbox", "box"));
    printf("Found at %i\n", findString("chatterbox", "boxx"));
    
 return 0;
    
}


int  findString (const char  source[], const char  s[])
{
    int  i, j, foundit = false;

    // try each character in source 

    for ( i = 0;  source[i] != '\0'  &&  !foundit;  ++i ) {
        foundit = true;

        // now see if corresponding chars from s match 

        for ( j = 0;  s[j] != '\0' &&  foundit;  ++j )
            if ( source[j + i] != s[j] || source[j + i] == '\0' )
              foundit = false;

        if (foundit)
           return i;
    }

    return -1;
}

that is what it looks like right now, you are suggesting to do it with pointers directly, do it without an index? Can you explain to me a little more please, thanks for the help, I am having trouble grasping pointers.
 

subsonix

macrumors 68040
Feb 2, 2008
3,551
79
It's always helpful with a small comment about what the code is suppose to do, if you want help, that was my point. Anyway, this is a simple example (my simple attempt which might have errors in it) but it shows the principle behind what I meant.

Code:
char *findString(char *source, char *s) {
    char *found = NULL;

    for(; *source != 0 ; source++) {
        for(found = source; *source == *s && *s != 0 && *source != 0; source++, s++ ) {
            if( s[1] == 0 )
                return found -1;
        }
    }
    return NULL;
}

Code:
int main()
{
    char *source = "sub-string";
    char *s = "string";
    char *found = NULL;

    found = findString(source, s);
    if( found )
        puts(found);
    else
        puts("Not found");


    return 0;
}
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
That is true, but if the choice lays between, s and *(s + i), why not use the more clear: s?


Personally, I can't see any reason to use *(s + i) over s. I've never used the former syntax in my own code.

Code:
char *findString(char *source, char *s) {
    char *found = NULL;

    for(; *source != 0 ; source++) {
        for(found = source; *source == *s && *s != 0 && *source != 0; source++, s++ ) {
            if( s[1] == 0 )
                return found -1;
        }
    }
    return NULL;
}

Great. I always forget about this technique of sliding a pointer along an array in C.

OP really analyse this code and you'll learn alot about pointers. Step through it expression at time, and notice and think about what happens and why it's happening.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,743
8,417
A sea of green
Personally, I can't see any reason to use *(s + i) over s. I've never used the former syntax in my own code.


Just because expressions are equivalent doesn't mean they have the same level of clarity. That's why C has a separate -> operator, which is precisely equivalent to an indirection followed by a dot: sp->sname is identical to (*sp).sname, only the former is a lot clearer than the latter, and easier to write. -> is especially useful in a sequence, such as sp->sptr->othername, which is pretty horrific with only * and . (left as an exercise for the reader).
 

dmi

macrumors regular
Dec 21, 2010
162
33
Personally, I can't see any reason to use *(s + i) over s. I've never used the former syntax in my own code.

Have you ever used *(s + 0) == *(s) over s[0] in your own code?
Or *(0 + i) == *i over 0 in your own code?
Or (s + i) over &s?
s+=i over s=&s?
 

Sander

macrumors 6502a
Apr 24, 2008
520
67
If the requirement for your findString() is that it returns the position at which the substring was found, you will have to keep around some kind of index anyway. In that case, I'd say your code won't become any clearer by using pointer arithmetic directly.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
Have you ever used *(s + 0) == *(s) over s[0] in your own code?
Or *(0 + i) == *i over 0 in your own code?
Or (s + i) over &s?
s+=i over s=&s?



Of these I have only ever used s + i over &s and s +=i over s = &s. But I don't get your point DMI.

I didn't/don't advocate explicit pointer arithmetic over array indexing. I just attempted to answer the OP's question "How would I go about using pointers in this function rather than array notation?".
 

MasConejos

macrumors regular
Jun 25, 2007
149
43
Houston, TX
As a side note, the inner loop can be replaced by the built in function strncmp, which means that both pointers and arrays are barely needed at all.

Code:
int  findString(const char* str, const char* matchStr)
{
	int ix = 0;
	int matchLength = strlen(matchStr);
	
	while(str[ix] != '\0')
	{
		if(strncmp(&str[ix], matchStr, matchLength) == 0)
		{
			return ix;
		}	
		ix++;
	}	
	return -1;
}
 

subsonix

macrumors 68040
Feb 2, 2008
3,551
79
That is true, but then you might as well use the function strstr() that finds a substring in a string. :)
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.