strend function in C using pointers?

I have created a function for strend, which basically returns 1 if string t is present at the end of string s, however it never returns 1:

#include <stdio.h> #include <string.h> #include <stdlib.h> int strend(char *s, char *t) { int p; for (p = 0; p < strlen(s) - strlen(t); p++) { *s++; } printf("%s\n%s\n", s, t); if (s == t) return 1; return 0; } int main(void) { int bool = strend("Hello", "ello"); printf("%i\n", bool); return 0; } 

This gives me an output of:

ello ello 0 

So technically I should get 1. I assume the comparison using pointers is not used in this way?

6

6 Answers

You need to review your basic knowledge of C strings. There are lots of standard string functions in string.h that can help you with this test.

The basic problem is that the test s == t is valid, but you are comparing memory addresses here. You can see that is valid if you change the strings to test to

char test[] = "Hello"; int bool = strend_(test, test+1); 

where test obviously is the same as your "Hello", and similarly, test+1 is the same as "ello" (try it by printing them). This correctly returns 1 with your routine.

In addition, I get two warnings:

  • on *s++; "warning: expression result unused [-Wunused-value]": you increment s but also ask what character is at that position through *s; and you don't use that information.
    Fix by removing the * there.

  • on p < strlen(s) ..; "warning: comparison of integers of different signs: 'int' and 'unsigned long'", because strlen does not return a signed integer but an unsigned one (apparently, my header uses unsigned long).
    Fix by declaring p as unsigned long, or even better, size_t.

Your entire routine can be condensed to a simple

int strend (char *s, char *t) { if (strlen(s) >= strlen(t) && !strcmp (s+strlen(s)-strlen(t),t)) return 1; return 0; } 

It's not worth the trouble to cache the result of those four strlen calls into 2 temporary variables; a good compiler will work it out and do that for you. (A quick glance to the assembly output of the compiler I'm using – clang – shows it does, even with the default optimization settings.)

A slightly modified test, based on @M.M.'s comment:

int strend (char *s, char *t) { if (strlen(s) < strlen(t)) return 0; return !strcmp (s+strlen(s)-strlen(t),t); } 

but attempting to optimize it this way is not as easy parsed as the routine above, and its assembly is ever so slightly "wordy" as well. Personally, I'd go for the more humanly readable version.

5

Use strcmp(3)

if (strcmp(s, t) == 0) return 1; 

This actually compares the contents of the memory pointed to by s and t rather than their addresses.

Your code is broken in multiple ways:

  • The initial loop is a very cumbersome way to advance p by the difference of lengths if positive.

  • Once you have pointers at the same distance from the end of both strings, You should compare the characters with strcmp() (or memcmp() if you can first exclude the case of strlen(s) < strlen(t).

  • Comparing the pointers obtained after the loop will only work if t points inside the string pointed to by s, a special case that may or may not be produced by the compiler for the specific call in main: strend("Hello", "ello");.

Here is a modified version:

#include <string.h> int strend(const char *str1, const char *str2) { size_t len1 = strlen(str1); size_t len2 = strlen(str2); return len1 >= len2 && !memcmp(str1 + len1 - len2, str2, len2); } 
2

I corrected/modified your code, here is the code,

#include <stdio.h> #include <stdlib.h> #include <string.h> //#pragma warning(disable:4996) int strend(char *s, char *t) { int p,flag=0,count=0;//count will be the starting index for *t p = strlen(s) - strlen(t);//this will be the starting index for *s while(count<strlen(t)) { if (*(s+p) == *(t+count)) { flag = 1; count++; p++; continue; } else { flag = 0; break; } } return flag; } int main(void) { int flag = strend("Hello", "ello"); printf("%i\n", flag); return 0; } 
3

This code works too.

#include <stdio.h> #include <string.h> int strend (char *s1, char *s2); void main () { char str1[20] = "somethings"; char str2[20] = "things"; int f; f = strend (str1,str2); if (f==1) printf ("1"); else printf ("0"); } int strend (char *str1, char *str2) { int l = strlen(str1) - strlen(str2); str1 = str1 + l; int d = strcmp(str1,str2); if (d == 0) return 1; else return 0; } 
1

this code works well.

int strend(char *s, char *t){ while(*t & *s){ if(*t == *s){ t++; } s++; } return *t==*s; } 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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

You Might Also Like