Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Occurences of char* in another char* 3

Status
Not open for further replies.

craigsboyd

IS-IT--Management
Nov 9, 2002
2,839
US
Say I have the following...

char *Phrase = "Hello World"
char *Letter = "o"

What's the best way to find the total number of occurrences of Letter in the Phrase?



boyd.gif

SweetPotato Software Website
My Blog
 
caraigsboyd,

Something like this should do the job:

char *Phrase = "Hello World";
char *pdest;
char letter = 'o';
int result;
int nCount = 0;

pdest = strchr( Phrase, letter );
while(pdest != NULL)
{
result = pdest - Phrase + 1;
pdest = strchr( Phrase + result, 'o' );
nCount = nCount + 1;
}


cdraycott

 
simple way:

char *Phrase = "Hello World";
char letter = 'o';
int count=0;
for (int i=0; i<strlen(phrase); i++){
if (letter==Phrase){
count++;
}
}
 
that is if you want it to be case sensitive...

if you don't want it to be case sensitive, you can:
-convert everything to either upper or lower case.
-subtract a constant (i cna't remember what it is).. ie you can subtract this constant like this:

if (letter==phrase || letter==phrase-constant)

there are many ways to do it if you want it to be case sensitive
 
My apologies to you both for the delay in replying...

Using your examples as a guide I came up with the following:
Code:
	char *pchPhrase = "Hello World";
	char *pchDelimit = "o";

	for (unsigned int i=0; i<strlen(pchPhrase); i++)
	{
		 if (*pchDelimit==pchPhrase[i])
		 {
			 count++;
		 }
	}

I had to use the char pointers as is since I cannot change the type of the parameters sent in to my function. The actual function code is much more complex than this, but I knew if I could get the Hello World example to fly then I could modify it to suit my needs.

Thank you both for your efforts on my behalf. Stars to you both.

boyd.gif

SweetPotato Software Website
My Blog
 
Some addition: strictly speaking, to satisfy requirements literally, we must accept any length substrings (because of we have a char pointer, not a char as parameter type).
See this code:
Code:
int SubStrCnt(const char* phrase, const char* psubs)
{
  if (!phrase || !psubs)
     return 0;
  int plen = strlen(phrase);
  int slen = strlen(psubs);

  if (plen == 0 || slen == 0 || plen < slen)
     return 0;
  int  n = 0;
  char ch;
  if (slen == 1) // char occurences
  {
     ch = *psubs;
     for (int i = 0; i < plen; ++i)
         if (phrase[i] == ch)
	    ++n;
  }
  else // non-trivial substring occurences
  {
    while ((phrase=strstr(phrase,psubs)) != 0)
	phrase += slen, ++n;	
  }
  return n;
}
 
ArkM,

I like the way you think. I would need to strdup() phrase as I use strok for parsing later on, but definitely good stuff. A question, why did you feel the need to create variable ch? Maybe it's just your coding style, but I want to make sure I'm not missing a hidden risk using *psubs directly.

boyd.gif

SweetPotato Software Website
My Blog
 
This works with all size search terms I think, from my thread:
Code:
int Instr( char *SearchString, char *SearchTerm,)
{
	int stringSize = lb::Len( SearchString );
	int termSize = lb::Len( SearchTerm );

    if ( termSize > stringSize )
    {
        return 0;
    }

    int numberFound = 0;
    const char* subString = NULL;

    for ( int i = 0 ; i <= stringSize - termSize; ++i )
    {
        if ( strncmp( &SearchString[ i ], SearchTerm, termSize ) == 0 )
        {
            ++numberFound;
        }
    }
    
    return numberFound;
}
 
I posted this function in the other similar thread, but if you're using C++, why not:
Code:
#include <iostream>
#include <string>

unsigned FindInStr(const std::string& src, const std::string& trm)
{
    unsigned numOccurrences = 0;
    size_t loc = 0;
    while (loc < src.size() &&
          (loc = src.find(trm, loc)) != std::string::npos)
    {
        ++numOccurrences;
        ++loc;
    }
    return numOccurrences;
}

int main()
{
    const char *Phrase = "Hello World";
    const char *Letter = "o";

    unsigned num = FindInStr(Phrase, Letter);
    std::cout << "Found \"" << Letter;
    std::cout << "\" " << num << " times." << std::endl;
}
 
whether or not to support multicharacter substrings is a matter for the function's documentation, altho i agree that failing to do so (given that the substring is not a w_char/char argument) is somewhat impolite.

whatever you do, just get that call to strlen() out of the loop!
 
craygsboid,
of course, ch var declaraion is not on principle. I don't like to keep redundant ops in body loops. Auto var access is a very fast, but parameter dereferencing is (potentially) slower. Yes, an optimizing compiler does the same job, but (I think;) ch var makes a text clear...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top