Google Answers Logo
View Question
 
Q: C++ code for countstr ( No Answer,   2 Comments )
Question  
Subject: C++ code for countstr
Category: Computers > Programming
Asked by: usf-ga
List Price: $5.00
Posted: 08 Nov 2003 15:30 PST
Expires: 08 Dec 2003 15:30 PST
Question ID: 273945
int ism_countstr(const char *buf, const char * str)

Returns the number of occurences of str within the string buf. For
example: ism_countstr ("Hello World","l") would return 3.

I need some help gettin this code started. I dont understand how to
generate the code.
Answer  
There is no answer at this time.

Comments  
Subject: Re: C++ code for countstr
From: mathtalk-ga on 08 Nov 2003 20:24 PST
 
Hi, usf-ga:

This function would most likely be written simply using C++ as "a
better C".  That is, it appears the desired function semantics are for
null-terminated character strings, as in C, and that no class
constructs are needed, just a bit of pointer arithmetic and looping.

You might want to write a "helper" function, ism_frontstr, which takes
the same kinds of arguments and simply returns 1 or 0 accordingly as
whether the beginning of the string buf contains a complete copy of
the string str.

The function ism_countstr can then be implemented by repeatedly
calling that helper function, using the same match string str each
time, but incrementing the pointer to "buf" until the end of buf is
reached.  Summing the return values of ism_frontstr invoked in this
manner will tell you how many occurences of str there are within the
string buf.

Note however that the occurences counted in this fashion may overlap,
which may or may not be what you intend here.  An example will clarify
the point.  Suppose the strings involved are:

buf = "LALALALA"

str = "LAL"

Now there are three distinct substrings of buf that match with str,
but only two which don't overlap.

After you write the function using the "helper" implementation, I'm
sure it will be clear to you how to get rid of it and do the entire
code "in line".

regards, mathtalk-ga
Subject: Re: C++ code for countstr
From: phaedo-ga on 16 Nov 2003 06:34 PST
 
Both C and C++ provide access to a set of library functions that are
standard accross implementations.  This library includes a set of
string and character manipulation functions.  One function, strstr(),
provides the information needed to create a function that would do
what you need.

You state that you need the following:

int ism_countstr(const char *buf, const char * str) 

The basic function would take on this form:

int ism_countstr(const char *buf, const char * str)
{
    return (0);
}

This is now valid C/C++ code that could be called by another function.  

Using your test data, a simple calling program which would write a
command windows would look like this:

#include <stdio.h>

int main()
{
    int count;
	
    count = ism_countstr("Hello World","l");
    printf ("count = %d\n", count);
}

This program would use the test example you provided, call
ism_countstr, and print out the returned value using the time-honored
"printf" function.  Unfortunately, it would always return zero and
therefore usually be wrong.

To make it usually be right, use the "strstr" function that I
mentioned above.  To find the prototype for "strstr", look up the
prototype for the function in the header file "string.h" if you are
using Microsoft Visual C++.  Unfortunately, this is not the same
accross compilers.  If you are using Borland's C++, the header file is
called "strings.h".

Strstr looks something like this:

    int strstr(const char *sting, const char *substring);

The "const" prefix for "char" tells us that the content of the string
will not be modified durign procesing: strstr won't mess with the
strings we provide to it.  That suggests that we need to use a
variable to contain the result of a call to "strstr" that can be
modified.

When we call strstr, the function returns a poiter to the first place
in the string that constains the substring.  Using the data you
provided, it would return a pointer to the first "l".  If you printed
this string, it would now say "llo, world".

To get to the next instance of "l", you have to coax the pointer to
the next location in the string and now use this new location as the
input to the next call to strstr.  We also have to count the fact that
we found the substring.

The new code would look like this:

int ism_countstr(const char *buf, const char * str)
{
    char *ptr = (char *) buf; // cast the buf pointer to a 
                              // non-constant char pointer
    int count = 0;

    ptr = strstr(ptr, str);
    if (ptr != NULL)
    {
                              // ptr now points to a string: "llo, world"
        count++;              // add 1 to count since we found "l"
        ptr++;                // move returned pointer from "l"
                              // ptr now points to a string: "lo, world"
    }
    return (count);           // will return 0 if no "l", 1 if "l" found
}

Now the function works a little better, but still is often wrong. To
make it more right, we have to put the "strstr" function in a loop
that will move through the string until it has found all of the
substrings.  To do this, we have to check for a NULL return before
recalling "strstr".

The new code including a "while" loop, looks like this:

int ism_countstr(const char *buf, const char * str)
{
    char *ptr = (char *) buf; // cast the buf pointer to a 
                              // non-constant char pointer
    int count = 0;

    while ((ptr = strstr(ptr, str)) != NULL)
    {
                              // ptr now points to a string: "llo, world"
        count++;              // add 1 to count since we found "l"
        ptr++;                // move returned pointer from "l"
                              // ptr now points to a string: "lo, world"
    }
    return (count);           // will return 0 if no "l", 1 if "l" found
}

The "while" statement evaluates the value of "ptr" to determine
whether it contains a valid pointer or a NULL pounter.  If "ptr" is
NULL, the substring was not present in the string.

This function can be called from C or C++ programs.

As to the comments from an earlier poster, the function will not find
overlapping instances of the substring within the string.  This
function also handles an empty string.  One additional test should be
done to handle pointers to bad strings.

Example: string "Hello, World".

The string takes up 12 locations to store the characters and an
additional location to store the terminator to the string.  In C/C++,
this is a character with a value of zero.  Therefore, the string looks
like this:

Hello, World*
1234567890123

The thirteenth character, that I chose to represent as a *, contains a
non-printable value of zero, not the number 0.  The code above
successfully tests for this value by setting the value of "ptr" to
point to the string location occupied by the "zero" value.  When we
test this value, it will work correctly.

But...

If we create a string pointer ("ptr") but do not set it to a valid
location, "ptr" itself is now a NULL string pointer.  In other words,
it does not point to a location containing a zero but "ptr" itself
contains a zero.  This will always lead to an error.  To test for
this, modifiy the  code to do the following:

#define ERR_BAD_STRING       -1    // error return value for bad string
#define ERR_BAD_SUBSTRING    -2    // error return value for bad substring

int ism_countstr(const char *buf, const char * str)
{
    char *ptr;
    int count = 0;

    if (buf == NULL)          // check to see whether buf is a NULL pointer
        return (ERR_BADSTRING);

    if (str == NULL)          // check to see whether str is a NULL pointer
        return (ERR_BADSUBSTRING);

    ptr = (char *) buf;               // cast the buf pointer to a 
                                      // non-constant char pointer

    while ((ptr = strstr(ptr, str)) != NULL)  // check to see whether
                                      // "ptr" points to an empty string
    {
                              // ptr now points to a string: "llo, world"
        count++;              // add 1 to count since we found "l"
        ptr++;                // move returned pointer from "l"
                              // ptr now points to a string: "lo, world"
    }
    return (count);           // will return 0 if no "l", 1 if "l" found
}

The calling program has to know that a zero return value means that
there are zero substrings and that a negative return is now an error
code.  In the old days, one never used the return of a function
without testing for errors.  This could also be implemented in C++
using an exception hnadler to achieve a similar effect.

That's all she wrote.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy