Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Implementing strstr

Reply
Thread Tools

Implementing strstr

 
 
spinoza1111
Guest
Posts: n/a
 
      03-19-2010
In the replace() program of last month's flame festival, a little
program was trying to get out. Here it is: an implementation of strstr
including a call that returns the offset of the found substring. Two
hours including all comments and dedicatory ode, written for this
occasion.

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

// ************************************************** *************
// * *
// * strstr *
// * *
// * This function (strstr) finds a string, probably as fast as *
// * possible without extra memory usage over and above brute *
// * force. *
// * *
// * In searching a Nul terminated string for a substring, there *
// * are logically three possibilities in a left to right *
// * traversal of the master string that (1) looks for the *
// * first character of the target and then (2) matches all the *
// * remaining characters:
// * *
// * * (Erroneous): on the failure of a partial match, *
// * restart at the first nonmatching character. This is *
// * fast but wrong, since the matching string may *
// * overlap the partial match. *
// * *
// * * (Too slow): on the failure of a partial match, start*
// * one past the first character (of the partial match) *
// * *
// * * (Just right): while matching characters, note the *
// * leftmost character in the searched string, to the *
// * right of the first matched character, that matches *
// * both that character and, of course, the first *
// * character of the target. *
// * *
// * C H A N G E R E C O R D --------------------------------- *
// * DATE PROGRAMMER DESCRIPTION OF CHANGE *
// * -------- ---------- --------------------------------- *
// * 03 18 10 Nilges Version 1.0 *
// * *
// * ----------------------------------------------------------- *
// * *
// * To find a string, oh Muse! I sing, inside another String! *
// * Alternatives to me come in Three, ah, that's the thing: *
// * For the one thing for which the Wise must watch is mayhap, *
// * Partial occurences that most melancholy, overlap. *
// * The first is base, mechanical, low, and tragicomical: *
// * It's to restart from the previous beginning plus but One *
// * Oh what Mayhem to true Programming is thereby, done! *
// * But the job it will do, as did Hercules, *
// * His Labors for the Goddess cruel in Seneca's tragedies: *
// * Arduously and ignobly like unto the meanest Hind *
// * That knoweth not his Elbow from his Behind. *
// * The second is worse, a boner, a solecism, and a Seebach: *
// * The second restarts at the character that doth match! *
// * Oh muse! Such hellish Sights before me yawn: *
// * But be assur'd, 'tis darkest just before the Dawn. *
// * Shout for Victory, oh Thrace, and smite the Harp, and Grin: *
// * For lo, we start at the leftmost "handle" of the string *
// * When it occureth in *
// * The tragic partial match that hath failed us. *
// * If no such handle exists, then we can restart *
// * At the point of match failure: no, 'tis not a brain fart. *
// * Now we spy our magic bus: *
// * For this is the best Al Gore ithm *
// * That we can hope for in C, a language without Rhyme, or *
// * for that matter, Oh Muse! rhythm. *
// * *
// ************************************************** *************

#define TRUTH -1
#define FALSITY 0
#define NULLITY 0

char * strstrWithIndex(char *strMaster,
char *strTarget,
int *ptrIndex)
{
char *ptrMaster = NULLITY;
char *ptrTarget = NULLITY;
char *ptrHandle = NULLITY;
int booFound = FALSITY;
if (!*strMaster || !*strTarget) return 0;
for (ptrMaster = strMaster; *ptrMaster
{
for (;
*ptrMaster && *ptrMaster != *strTarget;
ptrMaster++);
ptrTarget = strTarget;
*ptrIndex = ptrMaster - strMaster;
ptrHandle = 0;
for (;
*ptrTarget
?
(*ptrMaster
?
(*ptrMaster==*ptrTarget ? TRUTH : FALSITY)
:
FALSITY)
:
(booFound = TRUTH, FALSITY);
ptrMaster++, ptrTarget++)
{
if (ptrHandle = 0
&&
ptrMaster > strMaster
&&
*ptrMaster == *strTarget)
ptrHandle = ptrTarget;
}
if (booFound) return strMaster + *ptrIndex;
if (ptrHandle) ptrMaster = ptrHandle + 1;
}
*ptrIndex = 0;
return 0;
}

char * strstr(char *strMaster, char *strTarget)
{
int ptrIndex = 0;
return strstrWithIndex(strMaster, strTarget, &ptrIndex);
}

int main(void)
{
char *ptrIndex1 = NULLITY;
int intIndex1 = 0;
printf("strstr Simplified\n\n");
printf("Expect 0: %d\n", strstr("", ""));
printf("Expect 0: %d\n", strstr("0123456789", ""));
printf("Expect 0: %d\n", strstr("", "0"));
printf("Expect 0: %d\n", strstr("Here", "There"));
ptrIndex1 = strstrWithIndex("There", "here", &intIndex1);
printf("Expect 1: %d\n", intIndex1);
ptrIndex1 = strstrWithIndex("They seek him here",
"here",
&intIndex1);
printf("Expect 14: %d\n", intIndex1);
ptrIndex1 = strstrWithIndex("They seek him there",
"here",
&intIndex1);
printf("Expect 15: %d\n", intIndex1);
ptrIndex1 = strstrWithIndex
("The clc regs seek him everywhere",
"here",
&intIndex1);
printf("Expect 28: %d\n", intIndex1);
printf("Expect 'h': %c\n", *ptrIndex1);
ptrIndex1 = strstrWithIndex
("Is he in Heaven? Or in Hell?",
"?",
&intIndex1);
printf("Expect 15: %d\n", intIndex1);
printf("Expect '?': %c\n", *ptrIndex1);
ptrIndex1 = strstrWithIndex
("That damn'd elusive Spinoza won't tell!",
"Spinoza",
&intIndex1);
printf("Expect 20: %d\n", intIndex1);
printf("Expect 'p': %c\n", *(ptrIndex1+1));
printf("Expect '0': %c\n", *strstr("0123456789", "0"));
printf("Expect '1': %c\n", *strstr("0123456789", "1"));
printf("Expect '0': %c\n", *strstr("0123456789", "0"));
printf("Expect '9': %c\n", *strstr("0123456789", "9"));
printf("Expect '5': %c\n", *strstr("0123456789", "345") + 2);
printf("Expect '8': %c\n", *strstr("0123456789", "89"));
ptrIndex1 = strstrWithIndex("0123456789A89AB",
"89AB",
&intIndex1);
printf("Expect 11: %d\n", intIndex1);
return 0;
}
 
Reply With Quote
 
 
 
 
Dr Malcolm McLean
Guest
Posts: n/a
 
      03-19-2010
On 19 Mar, 10:34, spinoza1111 <(E-Mail Removed)> wrote:
>
> // * This function (strstr) finds a string, probably as fast as **
> // * possible without extra memory usage over and above brute * **
> // * force. * * * * * * * * * * * * * * * * * * * * * * * * * * **
>

There's a faster algorithm if a) the search string is long, and b) you
know the characteristics of the strings (natural English language,
protein sequence C code etc).

This is to scan the query string and take the two characters with the
least probability of appearing in your set. Eg for English language,
if the query is "quaker" you'd take 'q' and 'k'. Ypou then scan
looking only for that pair. If you find an exact match to the pair ypu
do a full scan.
 
Reply With Quote
 
 
 
 
spinoza1111
Guest
Posts: n/a
 
      03-19-2010
On Mar 19, 7:24*pm, Dr Malcolm McLean <(E-Mail Removed)>
wrote:
> On 19 Mar, 10:34, spinoza1111 <(E-Mail Removed)> wrote:
>
> > // * This function (strstr) finds a string, probably as fast as **
> > // * possible without extra memory usage over and above brute * **
> > // * force. * * * * * * * * * * * * * * * * * * * * * * * * * * **

>
> There's a faster algorithm if a) the search string is long, and b) you
> know the characteristics of the strings (natural English language,
> protein sequence C code etc).
>
> This is to scan the query string and take the two characters with the
> least probability of appearing in your set. Eg for English language,
> if the query is "quaker" you'd take 'q' and 'k'. Ypou then scan
> looking only for that pair. If you find an exact match to the pair ypu
> do a full scan.


Interesting insight. I'd add a third overload allowing an optional
ranking of characters, with a #define symbol giving the ranking for
English text. I don't want the program to "learn" by remembering older
frequencies, since that is state, and state is best handled by object
oriented languages.

Why not scan for the least frequent character and then look around it
to see if it is in a substring?
 
Reply With Quote
 
spinoza1111
Guest
Posts: n/a
 
      03-19-2010
On Mar 19, 7:38*pm, Branimir Maksimovic <(E-Mail Removed)> wrote:
> On Fri, 19 Mar 2010 03:34:06 -0700 (PDT)
>
> spinoza1111 <(E-Mail Removed)> wrote:
>
> > // ************************************************** *************
> > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> > // * strstr * * * * * * * * * * * * * * * * * * * * * * * * * * **
> > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> > // * This function (strstr) finds a string, probably as fast as **

>
> Problem with strstr is that there is no strnstr.
> For example:
>
> * if(!strcmp(readBuf_,"\r\n"))
> * {
> * *rc = true;
> * }
> * else if((end = strstr(readBuf_,"\r\n\r\n")) && size_t(end-readBuf_)<=readBufSize_)
> * {
> * * *res_.append(readBuf_,end-readBuf_);
> * * *rc = true;
> * }
>
> Disregard res_ as it is c++, but c++ doesn't have strnstr either!
> How to use strstr safely when there is o strnstr and you work
> with httpd 512 byte buffer eg?


I don't see the problem. "My" strstr simply assumes it will be passed
a Nul terminated string. If it falls off the edge of a cliff, isn't
this the user's problem?

I grant that there is a genuine problem in C tools that modify memory
such as printf. But in general, strstr and suchlike tools have no way
of protecting themselves that I'm aware of against bad data.
>
> Greets
>
> --http://maxa.homedns.org/
>
> Sometimes online sometimes not


 
Reply With Quote
 
spinoza1111
Guest
Posts: n/a
 
      03-19-2010
On Mar 19, 9:19*pm, pete <(E-Mail Removed)> wrote:
> spinoza1111 wrote:
>
> > In the replace() program of last month's flame festival, a little
> > program was trying to get out. Here it is: an implementation of strstr
> > including a call that returns the offset of the found substring. Two
> > hours including all comments and dedicatory ode, written for this
> > occasion.
> > * * printf("Expect 0: %d\n", strstr("", ""));
> > * * printf("Expect 0: %d\n", strstr("0123456789", ""));

>
> That's not what strstr is supposed to do.
> When the second argument to strstr points to an empty string,
> then strstr is supposed to return the first argument,
> which happens to be a non null pointer in the above cases.


Ill-defined. I don't choose to simulate mistakes, here. A null master
string is one in which a target string can never occur: a null target
could only occur in a null master string, but see rule one.

Perhaps I'm being narrow minded.

I suppose you could make a case, in a world biased towards left to
right, that all strings start with a magic invisible null string,
including a null master string.

So test for a null target, and if it is found, return the master
string's address and an index of 0 in strstrWithIndex().

Then, and only then, return 0 (not found) if the master string is
null.

You know what? Done.

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

// ************************************************** *************
// * *
// * strstr *
// * *
// * This function (strstr) finds a string, probably as fast as *
// * possible without extra memory usage over and above brute *
// * force. *
// * *
// * In searching a Nul terminated string for a substring, there *
// * are logically three possibilities in a left to right *
// * traversal of the master string that (1) looks for the *
// * first character of the target and then (2) matches all the *
// * remaining characters: *
// * *
// * * (Erroneous): on the failure of a partial match, *
// * restart at the first nonmatching character. This is *
// * fast but wrong, since the matching string may *
// * overlap the partial match. *
// * *
// * * (Too slow): on the failure of a partial match, start*
// * one past the first character (of the partial match) *
// * *
// * * (Just right): while matching characters, note the *
// * leftmost character in the searched string, to the *
// * right of the first matched character, that matches *
// * both that character and, of course, the first *
// * character of the target. *
// * *
// * C H A N G E R E C O R D --------------------------------- *
// * DATE PROGRAMMER DESCRIPTION OF CHANGE *
// * -------- ---------- --------------------------------- *
// * 03 18 10 Nilges Version 1.0 *
// * *
// * 03 19 10 Nilges Version 1.1 *
// * *
// * 1. Incorporates Pete's suggestion*
// * that a null target string is *
// * always found at the start of *
// * the master string. *
// * *
// * 2. Results display enhanced *
// * *
// * 3. Poem corrected (doth NOT *
// * match) *
// * *
// * ----------------------------------------------------------- *
// * *
// * To find a string, oh Muse! I sing, inside another String! *
// * Alternatives to me come in Three, ah, that's the thing: *
// * For the one thing for which the Wise must watch is mayhap, *
// * Partial occurences that most melancholy, overlap. *
// * The first is base, mechanical, low, and tragicomical: *
// * It's to restart from the previous beginning plus but One *
// * Oh what Mayhem to true Programming is thereby, done! *
// * But the job it will do, as did Hercules, *
// * His Labors for the Goddess cruel in Seneca's tragedies: *
// * Arduously and ignobly like unto the meanest Hind *
// * That knoweth not his Elbow from his Behind. *
// * The second is worse, a boner, a solecism, and a Seebach: *
// * The second restarts at the character that doth not match! *
// * Oh muse! Such hellish Sights before me yawn: *
// * But be assur'd, 'tis darkest just before the Dawn. *
// * Shout for Victory, oh Thrace, and smite the Harp, and Grin: *
// * For lo, we start at the leftmost "handle" of the string *
// * When it occureth in *
// * The tragic partial match that hath failed us. *
// * If no such handle exists, then we can restart *
// * At the point of match failure: no, 'tis not a brain fart. *
// * Now we spy our magic bus: *
// * For this is the best Al Gore ithm *
// * That we can hope for in C, a language without Rhyme, or *
// * for that matter, Oh Muse! rhythm. *
// * *
// ************************************************** *************

#define TRUTH -1
#define FALSITY 0
#define NULLITY 0

char * strstrWithIndex(char *strMaster,
char *strTarget,
int *ptrIndex)
{
char *ptrMaster = NULLITY;
char *ptrTarget = NULLITY;
char *ptrHandle = NULLITY;
int booFound = FALSITY;
*ptrIndex = 0; // Rel. 1.1
if (!*strTarget) return strMaster; // Rel. 1.1
if (!*strMaster) return 0; // Rel. 1.1
for (ptrMaster = strMaster; *ptrMaster
{
for (;
*ptrMaster && *ptrMaster != *strTarget;
ptrMaster++);
ptrTarget = strTarget;
*ptrIndex = ptrMaster - strMaster;
ptrHandle = 0;
for (;
*ptrTarget
?
(*ptrMaster
?
(*ptrMaster==*ptrTarget ? TRUTH : FALSITY)
:
FALSITY)
:
(booFound = TRUTH, FALSITY);
ptrMaster++, ptrTarget++)
{
if (ptrHandle = 0
&&
ptrMaster > strMaster
&&
*ptrMaster == *strTarget)
ptrHandle = ptrTarget;
}
if (booFound) return strMaster + *ptrIndex;
if (ptrHandle) ptrMaster = ptrHandle + 1;
}
*ptrIndex = 0;
return 0;
}

char * strstr(char *strMaster, char *strTarget)
{
int ptrIndex = 0;
return strstrWithIndex(strMaster, strTarget, &ptrIndex);
}

int main(void)
{
char *ptrIndex1 = NULLITY;
int intIndex1 = 0;
printf("strstr\n\n");
printf("Expect 0: %x\n", *strstr("", ""));
printf("Expect '0': '%c'\n", *strstr("0123456789", ""));
printf("Expect 0: %d\n", strstr("", "0"));
printf("Expect 0: %d\n", strstr("Here", "There"));
ptrIndex1 = strstrWithIndex("There", "here", &intIndex1);
printf("Expect 1: %d\n", intIndex1);
ptrIndex1 = strstrWithIndex("They seek him here",
"here",
&intIndex1);
printf("Expect 14: %d\n", intIndex1);
ptrIndex1 = strstrWithIndex("They seek him there",
"here",
&intIndex1);
printf("Expect 15: %d\n", intIndex1);
ptrIndex1 = strstrWithIndex
("The clc regs seek him everywhere",
"here",
&intIndex1);
printf("Expect 28: %d\n", intIndex1);
printf("Expect 'h': '%c'\n", *ptrIndex1);
ptrIndex1 = strstrWithIndex
("Is he in Heaven? Or in Hell?",
"?",
&intIndex1);
printf("Expect 15: %d\n", intIndex1);
printf("Expect '?': '%c'\n", *ptrIndex1);
ptrIndex1 = strstrWithIndex
("That damn'd elusive Spinoza won't tell!",
"Spinoza",
&intIndex1);
printf("Expect 20: %d\n", intIndex1);
printf("Expect 'p': '%c'\n", *(ptrIndex1+1));
printf("Expect '0': '%c'\n", *strstr("0123456789", "0"));
printf("Expect '1': '%c'\n", *strstr("0123456789", "1"));
printf("Expect '0': '%c'\n", *strstr("0123456789", "0"));
printf("Expect '9': '%c'\n", *strstr("0123456789", "9"));
printf("Expect '5': '%c'\n",
*strstr("0123456789", "345") + 2);
printf("Expect '8': '%c'\n", *strstr("0123456789", "89"));
ptrIndex1 = strstrWithIndex("0123456789A89AB",
"89AB",
&intIndex1);
printf("Expect 11: %d\n", intIndex1);
return 0;
}


>
> #include <stddef.h>
>
> char *str_str(const char *s1, const char *s2);
> size_t str_len(const char *s);
> char *str_chr(const char *s, int c);
> int str_ncmp(const char *s1, const char *s2, size_t n);
>
> char *str_str(const char *s1, const char *s2)
> {
> * * const int c = *s2++;
>
> * * if (c != '\0') {
> * * * * const size_t n = str_len(s2);
>
> * * * * s1 = str_chr(s1, c);
> * * * * while (s1 != NULL && str_ncmp(s1 + 1, s2, n) != 0) {
> * * * * * * s1 = str_chr(s1 + 1, c);
> * * * * }
> * * }
> * * return (char *)s1;
>
> }
>
> size_t str_len(const char *s)
> {
> * * size_t n;
>
> * * for (n = 0; *s != '\0'; ++s) {
> * * * * ++n;
> * * }
> * * return n;
>
> }
>
> char *str_chr(const char *s, int c)
> {
> * * while (*s != (char)c) {
> * * * * if (*s == '\0') {
> * * * * * * return NULL;
> * * * * }
> * * * * ++s;
> * * }
> * * return (char *)s;
>
> }
>
> int str_ncmp(const char *s1, const char *s2, size_t n)
> { * *
> * * const unsigned char *p1 = (const unsigned char *)s1;
> * * const unsigned char *p2 = (const unsigned char *)s2;
>
> * * for (; {
> * * * * if (n-- == 0) {
> * * * * * * return 0;
> * * * * }
> * * * * if (*p1 != *p2) {
> * * * * * * return *p2 > *p1 ? -1 : 1;
> * * * * }
> * * * * if (*p1 == '\0') {
> * * * * * * return 0;
> * * * * } * * * *
> * * * * ++p1;
> * * * * ++p2;
> * * }
>
> }
>
> --
> pete


 
Reply With Quote
 
spinoza1111
Guest
Posts: n/a
 
      03-19-2010
On Mar 19, 6:34*pm, spinoza1111 <(E-Mail Removed)> wrote:
> In the replace() program of last month's flame festival, a little
> program was trying to get out. Here it is: an implementation of strstr
> including a call that returns the offset of the found substring. Two
> hours including all comments and dedicatory ode, written for this
> occasion.
>
> #include <stdlib.h>
> #include <stdio.h>
>
> // ************************************************** *************
> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> // * strstr * * * * * * * * * * * * * * * * * * * * * * * * * * **
> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> // * This function (strstr) finds a string, probably as fast as **
> // * possible without extra memory usage over and above brute * **
> // * force. * * * * * * * * * * * * * * * * * * * * * * * * * * **
> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> // * In searching a Nul terminated string for a substring, there *
> // * are logically three possibilities in a left to right * * * **
> // * traversal of the master string that (1) looks for the * * * *
> // * first character of the target and then (2) matches all the **
> // * remaining characters:
> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> // * * * ** *(Erroneous): on the failure of a partial match, * * *
> // * * * * * restart at the first nonmatching character. This is *
> // * * * * * fast but wrong, since the matching string may * * * *
> // * * * * * overlap the partial match. * * * * * * * * * * * * **
> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> // * * * ** *(Too slow): on the failure of a partial match, start*
> // * * * * * one past the first character (of the partial match) *
> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> // * * * ** *(Just right): while matching characters, note the * *
> // * * * * * leftmost character in the searched string, to the * *
> // * * * * * right of the first matched character, that matches **
> // * * * * * both that character and, of course, the first * * * *
> // * * * * * character of the target. * * * * * * * * * * * * * **
> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *


One reason for submitting this was to show how very wrong it is to
claim that "nothing useful is learnt in uni".

Note, please, the three-way reasoning in the above. It selects three
cases which seem almost tangential to the focus of the code, where in
business it's sooooo important to be focused (in a pseudo-scientific
spirit that deserves to be described as the quick, attentive motions
of the servant and not the attention of the scientist).

But in logic the alternatives "just happen" to exhaust all possible
cases! Which means that if we focus as the scientist and not the
servant on each case in turn, we've proved something, which rarely, in
my experience, happens in the profit and rent seeking world.

I first encountered this type of disection, trisection, dilemma and
trilemma in a book on formal automata, and would have preferred to
encounter it in a college classroom cleared of thugs.
 
Reply With Quote
 
spinoza1111
Guest
Posts: n/a
 
      03-19-2010
On Mar 19, 8:28*pm, spinoza1111 <(E-Mail Removed)> wrote:
> On Mar 19, 7:38*pm, Branimir Maksimovic <(E-Mail Removed)> wrote:
>
>
>
>
>
> > On Fri, 19 Mar 2010 03:34:06 -0700 (PDT)

>
> > spinoza1111 <(E-Mail Removed)> wrote:

>
> > > // ************************************************** *************
> > > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> > > // * strstr * * * * * * * * * * * * * * * * * * * * * * * * * * **
> > > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> > > // * This function (strstr) finds a string, probably as fast as **

>
> > Problem with strstr is that there is no strnstr.
> > For example:

>
> > * if(!strcmp(readBuf_,"\r\n"))
> > * {
> > * *rc = true;
> > * }
> > * else if((end = strstr(readBuf_,"\r\n\r\n")) && size_t(end-readBuf_)<=readBufSize_)
> > * {
> > * * *res_.append(readBuf_,end-readBuf_);
> > * * *rc = true;
> > * }

>
> > Disregard res_ as it is c++, but c++ doesn't have strnstr either!
> > How to use strstr safely when there is o strnstr and you work
> > with httpd 512 byte buffer eg?

>
> I don't see the problem. "My" strstr simply assumes it will be passed
> a Nul terminated string. If it falls off the edge of a cliff, isn't
> this the user's problem?
>
> I grant that there is a genuine problem in C tools that modify memory
> such as printf. But in general, strstr and suchlike tools have no way
> of protecting themselves that I'm aware of against bad data.
>
>
>
>
>
> > Greets

>
> > --http://maxa.homedns.org/

>
> > Sometimes online sometimes not


I suppose that in rel. 1.3 I should check for NULL values of strMaster
and strTarget to forestall a Pedant Attack. But there is no SIMPLE
way, is there, of interrupting yourself as in a C Sharp try..catch
when you refer to memory that is not yours when a string without a Nul
terminator is passed to you.
 
Reply With Quote
 
Ersek, Laszlo
Guest
Posts: n/a
 
      03-19-2010
In article <20100319123852.523bdec1@maxa>, Branimir Maksimovic <(E-Mail Removed)> writes:

> Problem with strstr is that there is no strnstr.
> For example:
>
> if(!strcmp(readBuf_,"\r\n"))
> {
> rc = true;
> }
> else if((end = strstr(readBuf_,"\r\n\r\n")) && size_t(end-readBuf_)<=readBufSize_)
> {
> res_.append(readBuf_,end-readBuf_);
> rc = true;
> }
>
> Disregard res_ as it is c++, but c++ doesn't have strnstr either!
> How to use strstr safely when there is o strnstr and you work
> with httpd 512 byte buffer eg?


(Presumably I have no idea of the real topic of this thread, but I won't
let that disturb me.)

If you work with a "httpd buffer", you'll make that "char unsigned", not
plain char. Then you won't use strstr() but memmem() (not standard C) or
your own equivalent implementation.

#define _GNU_SOURCE
#include <string.h>

void *memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);

Finally, I hate to pull the EBCDIC card again (chill out, Kaz --
simply killfile me if you haven't done so yet), but "\r\n" is *not* what
you mean. RFC 2616 2.2 "Basic Rules" says,

CR = <US-ASCII CR, carriage return (13)>
LF = <US-ASCII LF, linefeed (10)>

So that would be, unless you say "this program works only with ASCII":

{
char unsigned buffer[BUFSIZE];
size_t loaded;

/* disservice to whomever signs your paycheck */
static const char unsigned crlf[] = { 0x0Du, 0x0Au };

char unsigned *found;

/* ... */

found = memmem(buffer, loaded, crlf, sizeof crlf);

/* ... */
}

lacos
 
Reply With Quote
 
Ersek, Laszlo
Guest
Posts: n/a
 
      03-19-2010
In article <20100319150531.194aee4b@maxa>, Branimir Maksimovic <(E-Mail Removed)> writes:

> One question here. In c++ Im pretty sure that when you write 0xff
> it defaults to unsigned type? Is that same in C or different.


C90 6.1.3.2 Integer constants

----v----
hexadecimal-constant
0x hexadecimal-digit
0X hexadecimal-digit
hexadecimal-constant hexadecimal-digit

[...]

The type of an integer constant is the first of the corresponding list
in which its value can be represented. Unsuffixed decimal: int, long
int, unsigned long int; unsuffixed octal or hexadecimal: int, unsigned
int, long int, unsigned long int; [...]
----^----

Same effect by C99 6.4.4.1 "Integer constants" p5.

C++98 and C++03 2.13.1 "Integer literals" p2:

----v----
[...] If it is octal or hexadecimal and has no suffix, it has the first
of these types in which its value can be represented: int, [...]
----^----

-> 0xff has type int "everywhere".

lacos
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      03-19-2010
On 2010-03-19, pete <(E-Mail Removed)> wrote:
> spinoza1111 wrote:
>> In the replace() program of last month's flame festival, a little
>> program was trying to get out. Here it is: an implementation of strstr
>> including a call that returns the offset of the found substring. Two
>> hours including all comments and dedicatory ode, written for this
>> occasion.


*snerk*

>> printf("Expect 0: %d\n", strstr("", ""));
>> printf("Expect 0: %d\n", strstr("0123456789", ""));


> That's not what strstr is supposed to do.


You're arguing with someone who is not a first-year CS student and
claims to have needed TWO HOURS to implement strstr.

Is there any genuine point in pointing out errors?

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / http://www.velocityreviews.com/forums/(E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
parsing using strstr Sean Bartholomew C++ 3 07-11-2004 10:34 PM
Re: memcmp versus strstr; reaction to chr(0) Burne C C Programming 3 07-25-2003 06:21 PM
Re: memcmp versus strstr; reaction to chr(0) Dan Pop C Programming 0 07-24-2003 05:51 PM
Re: memcmp versus strstr; reaction to chr(0) Thomas Matthews C Programming 0 07-24-2003 02:34 PM
Re: memcmp versus strstr; reaction to chr(0) Joona I Palaste C Programming 0 07-24-2003 10:37 AM



Advertisments