0

So I'm trying to get a grasp of pointers/arrays by creating a basic function, strend, that returns 1 if a substring occurs at the end of a given string and 0 if not. I realize I could accomplish this by measuring the length of a char array, subtracting the length of the substring from that length, and starting my program there, but I kind of want to do it the way my function does it to get a stronger grasp of pointer arithmetic. So here is the program:

#include <stdio.h>
#define NELEMS(x) (sizeof(x) / sizeof(x[0]))

int strend(char *string, char *substring, int substringLength){
    int count; /*keep track of how many number of chars that match in a row*/
    while(*string != '\0'){
        count = 0;
        while(*string == *substring){
            if (count + 1 == substringLength) return 1; /*if matches = length of str*/
            count++; 
            string ++;
            substring ++;
        }
    if (count == 0) string++; /*only increment outer loop if inner loop has done no work*/
    else {
        substring - count; /*reset substring, don't increment string... BUGGY*/
         }
    }
    return 0;
}

int main(){
    char string[] = "John Coltrane";
    char substring[] = "Coltrane";
    int substringLength = NELEMS(substring);
    printf("%d \n", strend(string, substring, substringLength));
    char string2[] = "John Coltrane is Awesome Coltrane";
    char substring2[] = "Coltrane";
    int substringLength2 = NELEMS(substring);
    printf("%d \n", strend(string2, substring2, substringLength2));
    return 1;
}

For the first test strings, string and substring, I get the right result, returning 1 because "Coltrane" is at the end of the string. Similarly, if I take the "Coltrane" out of string2, I get the correct result, returning 0 because the string does not end with Coltrane.

However, for the version of string2 that you see above, I also get zero, and the problem lies in the fact that strend does not reset substring after I iterate over it and increment it while it matches part of the main string. This is fine when the first instance of substring is at the end of the string, but not when there are two instances, as in string2. I thought that substring - count would decrement the pointer back to the beginning of the substring array, but it does not appear to be doing that.

If I change that expression with substring--, it does show the last character of the substring, but is an expression like for(int i = 0; i < count; i++, substring--) really the only way to do this?

Edit: Replacing substring - count with for(; count > 0; count--, substring--) seems like a pretty elegant one liner and it works for me, but I still have a gut feeling there's a better way.

1
  • 2
    That should be -= (compound assignment). Commented Feb 20, 2013 at 21:30

1 Answer 1

1

This is an expression which does not change the value of any variable:

substring - count;

This is how you change the value of the variable:

substring -= count;

The other error in your code is to only increment string when count is 0. What if there is a partial match like "Cole Slaw"?

Sign up to request clarification or add additional context in comments.

5 Comments

But I increment string and substring within the inner while loop, so if I were to do the increment when count != 0, I'd be skipping over a letter. The iterator would get to the l, increment to the e, exit the while loop after failing the condition, and then increment to the " " character without ever checking the e at the top of the loop (making sure it's not a '\0').
But after each failure you need to decrement to the start of each string before the next pass. Consider when you are trying to match the string "aaaaf". You might have a partial match with "aaabaaaaf".
I'm not sure I follow... The only string that needs to be decremented is the substring, because you need to test against that from the beginning. The actual string should never be decremented. If you enter the inner for loop and fail, the main string is still incremented because of string++, so you don't want to increment it again unless you never entered the inner loop (i.e., count = 0). Similarly, substring is decremented by the same number it was incremented, effectively reseting it, because of substring -= count.
Try printing string and substring at the bottom of your outer loop. Use string = "aaaf" and substring = "aaf".
By God, you're right... adding string -= (count - 1) in my else condition for the outer loop seems to clear up that issue, unless I'm missing something else.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.