ends_with() ?

R

Richard Tobin

CBFalconer said:
And here is mine - somewhat tortuous.

Your "endswith" may not work if either of the strings is a literal,
since it may be unmodifiable. It will also have bizarre effects
if the strings share storage.

-- Richard
 
R

RoSsIaCrIiLoIA

And here is mine - somewhat tortuous. endswith() alone is short.
I think I neglected to take care of the phrase being longer than
the searchee, which could cause UB.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Yes, I know strlcat and strlcpy are in the implementors
namespace. Change them if you must.
See <http://cbfalconer.home.att.net/download/strlcpy.zip>
for documentation and rationale.

The objective is to detect whether a given string terminates
another string. This is a fairly tortuous way of doing
"endswith", but is fairly clear.

By C.B.Falconer. Released to public domain
*/
/* does searchme end with the phrase phrase? */
/* illustrates the power of reversing things */
/* (if not the efficacy) */
static int endswith(char *phrase, char *searchme)
{
int result, lgh, i;

lgh = revstring(phrase); revstring(searchme);
result = 1;
for (i = 0; i < lgh; i++) /* strncmp if we had it */
if (phrase != searchme) {
result = 0; break;
}
revstring(phrase); revstring(searchme);
return result;
} /* endswith */

/* ---------------------- */

int main(int argc, char **argv)
{
char *searchme, *tmp;
size_t searchlgh;
int i;

if (argc < 3) puts("Usage: endswith phrase string");
else {
searchlgh = 1 + strlen(argv[2]);
searchme = malloc(searchlgh);
strlcpy(searchme, argv[2], searchlgh);
for (i = 3; i < argc; i++) {
/* append blank and argv to searchme */
searchlgh += (1 + strlen(argv));


why here searchlgh += (1 + strlen(argv)); and not
searchlgh += strlen(argv); ?
if (!(tmp = realloc(searchme, searchlgh))) break;
else {
searchme = tmp;
strlcat(searchme, " ", searchlgh);
strlcat(searchme, argv, searchlgh);
}
}
printf("\"%s\" does ", searchme);
if (!endswith(argv[1], searchme)) printf("not ");
printf("end with \"%s\"\n", argv[1]);
}


why here not "free(searchme);"?
return 0;
} /* main, endswith */



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define R return
#define W while


/* does searchme end with the phrase phrase? */
/* By RoSsIaCrIiLoIA */
static int endswith1(char *phrase, char *searchme)
{char *p1, *p2;
unsigned y1;
/*------------------------------*/
assert(phrase!=0 && searchme!=0);
p1=phrase+strlen(phrase); p2=searchme+strlen(searchme);

W(1){if(*p1!=*p2) R 0;
if(p2==searchme) R 1;
if(p1==phrase) R 0;
--p1; --p2;
}
}

int main(int argc, char **argv)
{
char *searchme, *tmp;
size_t searchlgh;
int i;

if (argc < 3)
puts(
"find \"string\" at end of \"phrase\".\nUsage: string phrase "
);
else {
searchlgh = 2 + strlen(argv[2]);
searchme = malloc(searchlgh+1);
strcpy(searchme, argv[2]);
for (i = 3; i < argc; i++) {
/* append blank and argv to searchme */
searchlgh += strlen(argv);
if (!(tmp = realloc(searchme, searchlgh))) break;
else {
searchme = tmp;
strcat(searchme, " " );
strcat(searchme, argv );
}
}
printf("\"%s\" does ", searchme);
if (!endswith1(searchme , argv[1])) printf("not ");
printf("end with \"%s\"\n", argv[1]);
}
free(searchme);
return 0;
} /* main, endswith */
 
K

Keith Thompson

RoSsIaCrIiLoIA said:
#define R return
#define W while
[SNIP]

#define X I will not waste my time reading any code that uses such \
ridiculous obfuscated macro definitions.

X
 
R

RoSsIaCrIiLoIA

int main(int argc, char **argv)
{
char *searchme, *tmp;
size_t searchlgh;
int i;

if (argc < 3) puts("Usage: endswith phrase string");
else {
searchlgh = 1 + strlen(argv[2]);
searchme = malloc(searchlgh);
strlcpy(searchme, argv[2], searchlgh);
for (i = 3; i < argc; i++) {
/* append blank and argv to searchme */
searchlgh += (1 + strlen(argv));


why here searchlgh += (1 + strlen(argv)); and not
searchlgh += strlen(argv); ?
if (!(tmp = realloc(searchme, searchlgh))) break;
else {
searchme = tmp;
strlcat(searchme, " ", searchlgh);
strlcat(searchme, argv, searchlgh);
}
}
printf("\"%s\" does ", searchme);
if (!endswith(argv[1], searchme)) printf("not ");
printf("end with \"%s\"\n", argv[1]);


here "free(searchme);"
why here not "free(searchme);"?

wrong
return 0;
} /* main, endswith */

int main(int argc, char **argv)
{
char *searchme, *tmp;
size_t searchlgh;
int i;

if (argc < 3)
puts(
"find \"string\" at end of \"phrase\".\nUsage: string phrase "
);
else {
searchlgh = 2 + strlen(argv[2]);
searchme = malloc(searchlgh+1);
strcpy(searchme, argv[2]);
for (i = 3; i < argc; i++) {
/* append blank and argv to searchme */
searchlgh += strlen(argv);
if (!(tmp = realloc(searchme, searchlgh))) break;
else {
searchme = tmp;
strcat(searchme, " " );
strcat(searchme, argv );
}
}
printf("\"%s\" does ", searchme);
if (!endswith1(searchme , argv[1])) printf("not ");
printf("end with \"%s\"\n", argv[1]); free(searchme);
}
free(searchme); ^^^^^^^^^^^^^^^^^^^^
wrong

return 0;
} /* main, endswith */
 
R

RoSsIaCrIiLoIA

Andreas said:
Nils said:
Andreas Klimas wrote:

Hello,

does anybody know about a standardfunction or a simpler way
to get this result.


Not really.

//Note: does not accept NULL pointers.


I would rather document that NULL pointers
would be accepted.
int ends_with(char *haystack, char *needle) {
int name_len = strlen(needle);
char *r = strstr(haystack,needle);
if(r != NULL)
return *r[name_len] == 0;

return 0;
}


/* more compact way */
int ends_with(char *haystack, char *needle) {
int name_len = strlen(needle);
char *r = strstr(haystack,needle);

return r&&!r[name_len];
}

/* deal with "hellolo" and "lo" */
int ends_with(char *haystack, char *needle) {
int name_len = strlen(needle);
char *r = haystack, *last = NULL;

while (r = strstr(r,needle))
last = r++;

return last&&!last[name_len];
}


Cheers
Michael

your ends_with() seems in a random array fast as my endswith1().
For your ends_with() there is the *wrong case* where e.g.
haystack="hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
and needle="h"
where your ends_with() seems 30 times slower (in my PC) than my
endswith1().
So my endswith1() is far better than your ends_with().
You see the code macro I see the errors. Are we peer?

Pass a program in the indent program is 1 second
find an error is 1 or more hours. If someone think different for me is
in error. It could be Bill Gates, Ken Thomson or Dennis Ritchie I
don't change if I have right.
 
R

RoSsIaCrIiLoIA

static size_t strlcpy(char *dst, const char *src, size_t sz)
{
const char *start = src;

if (src && sz--) {
while ((*dst++ = *src))
if (sz--) src++;
else {
*(--dst) = '\0';
break;
}
}
if (src) {
while (*src++) continue;
return src - start - 1;
}
else if (sz) *dst = '\0';
return 0;
} /* strlcpy */

I like very much these functions so I'm seeing to implement these.
I'm seeing strlcpy
Do you know that this seems not return the right len of dst?
This is my with my macros (at last it is not bugged)

size_t
strlcpy_m(char* dst, const char* src, size_t sz)
{size_t z=sz;
/*----------------------------*/
if( sz==0 ) G la;
if(src==0 ) G li; /* if dst==null could write it */
W( --sz && (*dst++ = *src++) );
--z;
if(!sz)
{li: *dst=0; }
la: R z-sz;
} /* strlcpy */
 
R

RoSsIaCrIiLoIA

I like very much these functions so I'm seeing to implement these.
I'm seeing strlcpy
Do you know that this seems not return the right len of dst?

Ok it is right: if sizeof(dst) < sz return strlen(src) and not
strlen(dst).

size_t
strlcpy_m(char* dst, const char* src, size_t sz)
{size_t z=sz;
/*----------------------------*/
if( sz==0 ) G l1;
if(src==0 ) G l0; /* if dst==null could write it */
W( --sz && (*dst++ = *src++) );
--z;
if(!sz)
{l0: *dst=0;
l1: if(src)
z+=strlen(src);
}
R z-sz;
} /* strlcpy */
 
B

BRG

RoSsIaCrIiLoIA said:
[snip]
Ok it is right: if sizeof(dst) < sz return strlen(src) and not
strlen(dst).

size_t
strlcpy_m(char* dst, const char* src, size_t sz)
{size_t z=sz;
/*----------------------------*/
if( sz==0 ) G l1;
if(src==0 ) G l0; /* if dst==null could write it */
W( --sz && (*dst++ = *src++) );
--z;
if(!sz)
{l0: *dst=0;
l1: if(src)
z+=strlen(src);
}
R z-sz;
} /* strlcpy */

If you genuinely want feedback here, I think you might get more if you
stopped using macros for 'while', 'return' etc.

I suspect that most people who use C will find this annoying.

Brian Gladman
 

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
474,159
Messages
2,570,879
Members
47,416
Latest member
LionelQ387

Latest Threads

Top