Archived

This topic is now archived and is closed to further replies.

phil05

Finding a single word within a string

Recommended Posts

phil05    100
I need a command in c++ that searches for the word "sword" within a sentence, stored in buffer[500]. For example, If buffer contains the word "sword" in its sentence, then output this.

Share this post


Link to post
Share on other sites
vaneger    100
well you have an issue first off...is the buffer sorted ? if it is you can search pretty fast using a binary search function. otherwise just search the buffer using a for loop to check every entry until you find it, i however would suggest sorting the buffer if possible because binary searches are much faster then linear for loop queries

Share this post


Link to post
Share on other sites
ZealousElixir    256
If you put that buffer in a std::string, you'll have the find(toFind ) function available. Otherwise, it's not too hard to imagine what you'll have to do:

short location = -1;
for(x = 0 to buffer length)
{
for(i = 0 to length of search term)
{
if(!buffer[x+i] == searchterm[ i])
location = -1;
location = x;
}

if(location >= 0)
return location;
}

That's the algorithm. Whether or not there's an ANSI C function that does it, I'm not sure.

Later,
ZE.

[edited by - zealouselixir on March 21, 2004 10:30:20 PM]

Share this post


Link to post
Share on other sites
hplus0603    11347
You want strstr(), which is good-old standard C library.

Of course, if you want DELIMITED words, then you want to do some fanciness with delimited streams, using std::copy() and putting each word into a list, and then using std::find() on that list instead.

Share this post


Link to post
Share on other sites
Boku San    428
It sounds like you''re trying to find a substring within another string ("stored in buffer[500]"), you could use

char *swd;

if((swd = strstr(buffer, "sword")) != NULL)
*do something*
else
*not found*

I ripped this from a book. It''s case-sensitive, but if you need another function that isn''t case-sensitive, write it out to strupr(first_string) strupr(second_string)...which I can post here if you can''t figure that out.



"TV IS bad Meatwad...but we f***in need it"

If you''re a girl under the age of 12, and you''re high on marijuana...don''t ride your bike. -TRUTH

Share this post


Link to post
Share on other sites
Parthon    247
It would probably also be faster if the line was also broken down into words first. You could also then speed it up by eliminating words that couldn''t possibly be it.

You might also have to be careful with certain results.

example:
player: "I''m going to kill you with my sword."
reply: "Oh, yes I have a sword. Here it is."

A language examiner is always complicated.

Share this post


Link to post
Share on other sites
phil05    100
Boku, I tried this but got an error..

error C2440: ''='' : cannot convert from ''char *'' to ''char [500]''
There are no conversions to array types, although there are conversions to references or pointers to arrays
Error executing cl.exe.


#include <iostream>
#include <string>

int main()
{
using std::cout;
using std::cin;
using std::endl;

char buffer[500];

cout << "Player -> ";
std::cin.getline(buffer, sizeof(buffer));

if ((buffer = strstr(buffer, "sword")) != NULL)
{
cout << "Yes." << endl;
}
else
{
cout << "No." << endl;
}

return 0;
}

Share this post


Link to post
Share on other sites
Desert Fox    277
I suggest you look up either the Boyer-Moore algorithm (which I think std::string::find uses), or if space isn''t a concern, the Suffix Search algorithm. The suffix search tends to be the fastest, but it eats up a fairly large amount of space. (About 4x the amount of space the original string uses). The algorithm mentioned by ZealousElixir is basically the naive algorithm, but if run-time isn''t a priority (or your search string is relatively small), then it''s fine to use it.

Share this post


Link to post
Share on other sites
phil05    100
Well, this worked but it didn''t let me ask for a sword in a sentence, such as "do you have a sword."


#include <iostream>
#include <string>

int main()
{
using std::cout;
using std::cin;
using std::endl;

char buffer[500];

cout << "Player -> ";
std::cin.getline(buffer, sizeof(buffer));

if ((buffer == strstr(buffer, "sword")) != NULL)
{
cout << "Yes." << endl;
}
else
{
cout << "No." << endl;
}

return 0;
}

Share this post


Link to post
Share on other sites
phil05    100
Heh... it seems like there would be a simple command that finds such a substring, but nope. It always has to be 20 lines to do one little thing.

Share this post


Link to post
Share on other sites
Boku San    428
Did you use any punctuation with "Do you have a sword?" If you did, I don''t think it will recognize it. But then again, I haven''t used anything too useful in a while.

If that doesn''t work, you could just use
if(strstr(buffer, "sword") != NULL)
*goodness*
else
*badness*

It looks like you''re assigning the buffer variable to a TRUE or FALSE, which, while ok, clears your buffer...so try that out.



"TV IS bad Meatwad...but we f***in need it"

If you''re a girl under the age of 12, and you''re high on marijuana...don''t ride your bike. -TRUTH

Share this post


Link to post
Share on other sites
TechnoGoth    2937
Well you could switch from char to string, which has multiple find functions for searching for substrings.

so:
string buffer;

if(buffer.find("sword")!=npos)
{
//due stuff
}



-----------------------------------------------------
Writer, Programer, Cook, I''m a Jack of all Trades
Current Design project
Chaos Factor Design Document

Share this post


Link to post
Share on other sites
Desert Fox    277
How about std::string::find?



#include <string>
#include <iostream>

int main()
{
std::string str;
std::getline(std::cin,str);

if (str.find("sword") != std::string::npos)
std::cout << "Found it" << std::endl;
else
std::cout << "Didn't find it" << std::endl;

return 0;
}



Of course, this will also find "swordfish", but it can be modified fairly easily to only find "sword".

Edit: Got beat to it

[edited by - desert fox on March 21, 2004 11:15:42 PM]

Share this post


Link to post
Share on other sites
phil05    100
Problem # 500
C:\Program Files\Microsoft Visual Studio\MyProjects\Practice2\Pract2.cpp(10) : error C2065: ''string'' : undeclared identifier
C:\Program Files\Microsoft Visual Studio\MyProjects\Practice2\Pract2.cpp(10) : error C2146: syntax error : missing '';'' before identifier ''buffer''
C:\Program Files\Microsoft Visual Studio\MyProjects\Practice2\Pract2.cpp(10) : error C2065: ''buffer'' : undeclared identifier
C:\Program Files\Microsoft Visual Studio\MyProjects\Practice2\Pract2.cpp(15) : error C2228: left of ''.find'' must have class/struct/union type
Error executing cl.exe.




#include <iostream>
#include <string>

int main()
{
using std::cout;
using std::cin;
using std::endl;

string buffer;

cout << "Player -> ";
std::cin.getline(buffer, sizeof(buffer));

if (buffer.find("sword") != NULL)
{
cout << "Yes." << endl;
}
else
{
cout << "No." << endl;
}

return 0;
}

Share this post


Link to post
Share on other sites
kendallemm    122
Howdy, noticed you were still having trouble.

The "string" error is likely because you're using string instead of std::string

Your "strstr" error is that you are trying to assign a char * to a char [] which doesn't work; char [] is more or less a
const char * -- you can't change the address it points to, even though it is still a pointer.

How strstr works is:
[code]
buffer [500] = [.|.|.|s|w|o|r|d|.|.|.|\0]
char * result;

result = strstr (buffer, "sword");
gets you:

[.|.|.|s|w|o|r|d|.|.|.|\0]
result --------^


So result = "sword...", and points into the original buffer.

Hope this helps!

KB

(modified because code tags should not be used lightly)

[edited by - kendallemm on March 21, 2004 11:44:15 PM]

Share this post


Link to post
Share on other sites
phil05    100
std::getline(std::cin,buffer);

This need''s a newline command. After pressing enter, it waits for you to press another ''enter'' til it goes to the person''s response.

I thought there was something like cin.put(''\n'') or something relating..?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
This is the same problem as parsing a GL extension string, except a little worse because there can be punctuation.

strstr and string::find will both give false positives on the sentence "What is your password?". When I had to do this with a GL extension string, I used an istream_iterator (istringstream) and a back_inserter to split the string up by words, and then you can do a std::find on the vector but you''ll have to deal with punctuation manually.

Using a regular expression will be more reliable, but you''ll have to find a regular expression library to link in. There is one in glibc on Linux.

Share this post


Link to post
Share on other sites