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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Instr() function 2

Status
Not open for further replies.

kriscs1

Programmer
Jul 5, 2005
12
GB
Hi,
I'm trying to make a function to count the occurences of a char or string in another string. (I know thee is a thread about this below but that is just for chars)
Please could someone tell me why my Instr() function does not work because I have no idea...
I presume it is to do with my mid() function.
Also, if you have time, would somebody please tell me how to free the memory in my mid function? (which is also pretty bad) Thanks very much. I'm a newbie and would appreciate any help (as long as I understand it :p)


char* Mid(char *Sentence, int FromNumber, int ToNumber)
{
char* newSentence = (char *) malloc(1000);

if (ToNumber == 0)
{
ToNumber = strlen(Sentence);
FromNumber = strlen(Sentence) - FromNumber;
}

ToNumber = ToNumber+FromNumber;

for (int i = (FromNumber--); i < ToNumber; i++)
{
*(newSentence+(i-FromNumber)) = *(Sentence+i);
}
*( newSentence + (ToNumber-FromNumber)) = 0;

return newSentence+1;
}



///////////////////////////////////////////////////////////



int Instr(char *SearchString, char *SearchTerm)
{
int ReturnValue = 0;
for (int i = 0 ; i <= strlen(SearchString)-strlen(SearchTerm); i++)
{
if (SearchTerm == Mid(SearchString, i, strlen(SearchTerm)))
{
ReturnValue ++;
}
}
return ReturnValue;
}
 
First of all, please put code inside [ignore]
Code:
[/ignore] blocks.
Next, why are you using malloc()?! Are you not allowed to use C++ code?
Now, about Instr()... In the if statement you are trying to compare two strings, but that isn't how you do it in C/C++. You need to either use the strcmp() function like this:
Code:
if ( strcmp( SearchTerm, Mid(SearchString, i, strlen(SearchTerm) ) == 0 )
or even better, use STL strings instead of char*, then you can use the == operator on them.
 
Hi,
umm.. I'm using malloc() because I was told to by someone and i can't get it to work without it. How can I do it without it? Isn't that C++ code?

If I try and use the strcmp() function it says this:
'argument' : conversion from 'size_t' to 'int', possible loss of data
'strcmp' : cannot convert parameter 2 from 'bool' to 'const char *'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast

Is there any website that explains STL string really simply?

Thanks very much
Kris
 
malloc() is an ancient C function. C++ uses the 'new' operator. For example:
Code:
char* Mid( char *Sentence, int FromNumber, int ToNumber = 0 )
{
	int strLen = strlen( Sentence );

	// Error!  User passed numbers in the wrong order, or the From or To numbers are out of range!
	if ( (ToNumber <= FromNumber) || (FromNumber > strLen) || (ToNumber > strLen) )
	{
		return NULL;
	}

	// Allocate space for the new string.
	// NOTE:  Calling function must delete this memory.
	int offset = ToNumber - FromNumber;
	char* newSentence = new char[ offset + 1 ];

	if ( ToNumber == 0 )
	{
		ToNumber = strlen( Sentence );
	}

	strncpy( newSentence, Sentence[ FromNumber ], offset );

	return newSentence;
}
After calling Mid(), don't forget to delete the string that was returned like this:
Code:
const char* subString = Mid( myString, 3, 22 );
delete [] subString;
Your Instr() function could also use a facelift:
Code:
int Instr( char *SearchString, char *SearchTerm )
{
	int stringSize = strlen( SearchString );
	int termSize = strlen( 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 )
		{
			i += termSize;	// Skip past this term.
			++numberFound;
		}
	}
	
	return numberFound;
}
 
Hi, thanks very much for that.
I couldn't get strlen() to work because it said it could not 'convert from size_t to int' but I just changed it to my own Len() function.

However, there is just one last error I cannot get to work.
'strncpy' : cannot convert parameter 2 from 'char' to 'const char *'

referring to the line:
Code:
  strncpy( newSentence, Sentence[ FromNumber ], offset );

thanks very much
Kris
 
What compiler are you using? What's the exact line of code that you're using?
 
If you're using VC++ 2005, then strncpy was deprecated in favor of strncpy_s:



By the way, here is one way to search for a char or string in another string in C++:
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()
{
    std::string text = "In theory, if the theatre is there,"
                       "then these tickets are authentic.";
    std::string searchStr = "the";
    char searchChar = 'e';

    unsigned num = FindInStr(text, searchStr);
    std::cout << "Found \"" << searchStr;
    std::cout << "\" " << num << " times." << std::endl;

    num = FindInStr(text, std::string(1, searchChar));
    std::cout << "Found '" << searchChar;
    std::cout << "' " << num << " times." << std::endl;
}
 
Wow, that's pretty stupid... Is there a way to force it to still use strncpy()?

What makes them think strncpy_s() is any more secure than strncpy()?
 
Deprecated is just a warning. You can still use it. The new version adds a null terminator, which sometimes you don't want, so strncpy is of course still available.
 
I'm using VC++. strncpy_s() requires 4 parameters ,not 3 like strncpy().

I changed it to this:
Code:
 strncpy_s(newSentence, sizeof(newSentence), &Sentence[FromNumber], offset);

However, if I use 0 and 3 as the firsts and second parameter, the function works. If I use 0 and 4 or anything higher, it says the buffer size is too samll.
 
0 and 3?? That would mean you're passing a NULL pointer. I don't understand?
 
I mean:
Mid("hello", 0 ,3) would output "hel"
The start point is 0 and it displays the next 3 characters.

Mid("hello", 0 ,4) howevers says the buffer size is too small.

Code:
	char* Mid( char *Sentence, int FromNumber, int ToNumber = 0 )
{
	int strLen = Len( Sentence );

	if (ToNumber == 0)
	{
		ToNumber = Len( Sentence );
		FromNumber = Len( Sentence ) - FromNumber;
	}
	else
	{
	ToNumber = ToNumber+FromNumber;
	}

    // Allocate space for the new string.
    // NOTE:  Calling function must delete this memory.
    int offset = ToNumber - FromNumber;
    char* newSentence = new char[ offset + 1 ];

    strncpy_s(newSentence, sizeof(newSentence), &Sentence[FromNumber], offset);

    return newSentence;
}
 
Is it the call to strncpy_s() that is giving you the error? If you print out the value of sizeof( newSentence ) what does it say?
 
yes, it is strncpy_s() that is giving my the error.
sizeof( newSentence ) seems to always be 4 no matter what which is obviosly why it is too small if I input 0 and 4 to the function......
 
Why are you using sizeof anyway? You know the length already: offset + 1.
 
That's right... You should be using: offset + 1

The reason you always get 4 is because sizeof() is returning the size of the pointer (which is always 32 bits) instead of the size of the array that the pointer is pointing to.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top