Programming Forums

Programming Forums (http://www.programmingforums.org/forumindex.php)
-   C (http://www.programmingforums.org/forum60.html)
-   -   Function that returns occurances of substring in string. (http://www.programmingforums.org/showthread.php?t=4661)

conbrio Jun 29th, 2005 2:55 PM

Function that returns occurances of substring in string.
 
I was sort of surprised there wasn't a function in C's libraries to deal with this..so I got to making it.

:

int strcnt(char cstr[], char cdlm[]) {
  int oc=0;
  for (strtok(cstr, cdlm); strtok(NULL, cdlm); oc++);
  return oc;
}


This would be fine and well, but I need strtok() to work with the same string (ie, the string fed into the first arg in strcnt) elsewhere in the program, in another function. When I try to use strtok() in a different function with the same string, the second time I call it (to get the second token split off by the delimiter) it returns <null>. So I'm guessing I need to somehow "reset" strtok() at the end of strcnt(). Is this possible?

L7Sqr Jun 29th, 2005 6:11 PM

Quote:

BUGS
Never use this function. This function modifies its first
argument. The identity of the delimiting character is
lost. This function cannot be used on constant strings.
From the man pages of strtok.
If you want to preserve the string being used, first make a copy and then use the copy to do your dirty work.
You could also, if so inclined, write your own version of strtok as well. ;)

Ancient Dragon Jun 29th, 2005 8:39 PM

Quote:

Originally Posted by conbrio
I was sort of surprised there wasn't a function in C's libraries to deal with this..

Here is another way to count the number of occurrences without using strtok()
:

int main()
{
        char str[] = "HelloHelloHello";
        int counter = 0;
        char*ptr = strstr(str,"Hello");
        while(ptr != 0)
        {
                counter++;
                ptr = strstr(ptr+1,"Hello");
        }
        printf("counter = %d\n",counter);
        return 0;

}


conbrio Jun 30th, 2005 12:48 PM

Thanks for alerting me to that L7Sqr. I looked at its man page and noticed that there is apparently something of a replacement for strtok() anyway (strsep()).

Ancient Dragon, that code works fine, thanks. I wasn't aware that if one incremented the pointer strstr() returns, it'd move to the next occurance of the substring..

The man page is kind of cryptic on the matter.

:

RETURN VALUE
      The  strstr()  function returns a pointer to the beginning
      of the substring, or NULL if the substring is not found.


Thanks again.

DaWei Jun 30th, 2005 1:57 PM

The pointer you pass represents the beginning of a string. There is no requirement that it be at the beginning of a defined array of char, only that the data from that point onwards qualifies as a string (zero or more char followed by a null terminator).

The pointer returned represents the beginning of the substring. If you increment the pointer from that position, that particular substring can no longer be found; only the characters beyond that position, up to the terminator, are subsequently searched.

Nuticulus Jul 1st, 2005 2:13 PM

Quote:

Originally Posted by Ancient Dragon
Here is another way to count the number of occurrences without using strtok()
:

int main()
{
        char str[] = "HelloHelloHello";
        int counter = 0;
        char*ptr = strstr(str,"Hello");
        while(ptr != 0)
        {
                counter++;
                ptr = strstr(ptr+1,"Hello");
        }
        printf("counter = %d\n",counter);
        return 0;

}


Wait a moment, wasn't it you who made the thread about using pre-incrementation as opposed to post incrementation? Just nitpicking :P

But anyway the code is a perfectly fine substitute for using strtok for that purpose. I never knew it was recommended not to use strtok before. Btw, I read the strsep() manpage and it appears to suffer the same problems as strtok(), i.e. it modifies the string. So it's not exactly a great substitute.

DaWei Jul 1st, 2005 5:51 PM

There is a remote chance that a post-increment of a complex object will take a clock cycle or two more than a pre-increment of the same object. For the hugely vast majority of such operations applied to simple or atomic types the code emitted by the compiler will be the same. One would always be safe, I suppose, with the pre-increment. I, however, despise self-anointed high-priest/gurus (let me be clear -- Ancient Dragon is NOT one) that have an endless bag of dictums with which to bury neophytes and enhance their power (e.g., "I said so, that's why"). In the hopes that I may cause one of these types to spit a frothy, bloody, bubble of rage on his/her homemade vestments, I almost always use the post-increment operator.

Ancient Dragon Jul 1st, 2005 6:51 PM

Quote:

Originally Posted by Nuticulus
Wait a moment, wasn't it you who made the thread about using pre-incrementation as opposed to post incrementation? Just nitpicking :P

No -- I doubt it. I have argued that pre and post increment are nearly, if not exactly, the same when NOT used in comparisons, such as when all you want to do is increment the number. That does NOT apply in the examples I show below, when it does make a big difference. The way I incremented counter in my post #3 is exactly the way I always increment counters.


Quote:

Originally Posted by DaWei
I almost always use the post-increment operator.

So do I. I think pre-increment makes for confusing code, and if there is an error, pre-increments can often be overlooked as the culprit. And it just seems to be a more natural way to do things -- evaluate the integer and then increment it. Example: I would write a loop as in the first example, never like the second.

:

int array[10];
int i = 0;
while(i < 10)
{
  cout << array[i++] << endl;
}


:

int array[10];
int i = -1;
while(i < 10)
{
  cout << array[++i] << endl;
}



All times are GMT -5. The time now is 2:34 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC