1. Welcome to the new MacRumors forums. See our announcement and read our FAQ

Strings and pointers in C

Discussion in 'Mac Programming' started by CsRookie, Apr 20, 2011.

  1. macrumors newbie

    #1
    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:
     
  2. macrumors 68040

    #2
    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.
     
  3. macrumors 65816

    jiminaus

    #3
    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';
    
     
  4. macrumors 68040

    #4
    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.
     
  5. macrumors newbie

    #5
    Thank you very much for the help :apple:
     
  6. macrumors newbie

    #6




    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.
     
  7. macrumors 68040

    #7
    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;
    }
    
     
  8. macrumors 65816

    jiminaus

    #8


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

    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.
     
  9. macrumors 603

    #9


    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).
     
  10. dmi
    macrumors regular

    #10

    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?
     
  11. macrumors 6502

    #11
    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.
     
  12. macrumors 65816

    jiminaus

    #12



    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?".
     
  13. macrumors regular

    #13
    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;
    }
    
     
  14. macrumors 68040

    #14
    That is true, but then you might as well use the function strstr() that finds a substring in a string. :)
     
  15. macrumors regular

    #15
    ...And somehow, despite having perused the header reference many times, I've always managed to miss that function. :eek:

    thanks!
     

Share This Page