Searching for the occurance of a string at the beginning of a larger string

Started by
8 comments, last by csxpcm 20 years, 10 months ago
Hi I''m trying to find the method call in C++ to find a substring occurance within a larger string. This will then determine if it should be read in. for instance, FG, Fred, 334, 45 FG, Tony, 321, 34 DB, Paul, 432, 54 FG, Eric, 433, 21 Only if the string starts with FG should it be read in. So assuming I have the following code, "line" is the string to search through (i.e. FG, Fred, 334, 45). string line; getline(in, line); Im stuck here, what method can I use from C++ to determine if it begins with FG. Thanks in advance for any help
Advertisement
Instead of reading in the whole line:

std::string first;
std::getline(inFile, first, ',');   // reads the first value, for example "FG", into a std::string

if (first == "FG") // if the first value is 'FG',
{
// do whatever
}


std::string has an overloaded equality operator (==), so you can compare strings.

[ Google || Start Here || ACCU || MSDN || STL || GameCoding || BarrysWorld || E-Mail Me ]

[edited by - Lektrix on May 26, 2003 12:46:58 PM]
[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || CUJ || MSVC++ Library Fixes || BarrysWorld || [email=lektrix@barrysworld.com]E-Mail Me[/email] ]
strstr() in string.h

or, just checking the first two characters:

strncmp( line, "FG", strlen("FG") )

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Hi
thanks for the suggestions!!
The problem is, when using getline to get the first occurance of the larger string, it detects it, but then back in the calling method, it doesnt work.
In the current code layout it doesnt output anything, and when the ''if'' loop body is set to end at the point //A, the calling function doesnt include the first string (the one we checked for), when setting the attributes of glass g.
i.e. the first sting ''valid'' isnt there anymore!
iss >> g.valid >> g.name >> g.score >> g.age;
I guess I have to reset it and move back to the beginning of the string?




  bool checkValid(istream& in){  std::string first;  std::getline(in, first, '','');  if (first == "$FG")	return true;  else	return false;}istream& operator>>(istream& in, CPEOPLE& g){  using std::replace_if;  istringstream iss;  string line;   bool isValid = checkValid(in);  if (isValid) {    cout << "VALID" << endl;  // A      getline(in, line);    replace_if(line.begin(),line.end(),isComma,'' '');    iss.str(line);      iss >> g.valid >> g.name >> g.score >> g.age;    return iss;  }}  

Yes, you could move back to the beginning of the string, or you could do this:

bool checkValid(std::istream& in, std::string& first)
{
std::getline(in, first, ',');

return first == "$FG"; // this is just a simpler way; it returns the result of first == "$FG"
}

std::istream& operator>>(std::istream& in, CPEOPLE& g)
{
using std::replace_if;

std::string first;
if (checkValid(in, first))
{
g.valid = first;
// you might want to put the line above at the end of the function, so that
// all the assignment of g's members are together, but bleh

std::cout << "VALID" << std::endl;

std::string line;
std::getline(in, line);
replace_if(line.begin(), line.end(), isComma, ' ');

std::istringstream iss(line);
iss >> g.name >> g.score >> g.age;
}

return in;
// before you had "return iss;" inside the if statement block, I think you meant "return in;"
// to be at the end of the function
}


As you can see, the checkValid() function stores the valid value (first) in the std::string that you pass to it. It then assigns this to g.valid. This saves having to go back to the start of the line and read into a string again, etc. Although it is not particularly neat, it is still OK. By the way, sorry but I felt the need to change some of the declarations of the objects to different places and change the code slightly. Bleh, I'm an efficiency boy.

[ Google || Start Here || ACCU || MSDN || STL || GameCoding || BarrysWorld || E-Mail Me ]

[edited by - Lektrix on May 26, 2003 1:57:00 PM]
[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || CUJ || MSVC++ Library Fixes || BarrysWorld || [email=lektrix@barrysworld.com]E-Mail Me[/email] ]
Thanks Lektrix and S1CA!
But Lektrix, there one thing I dont understand.
With the checkValid function you defined, it does''t evaluate to True or False. Therefore, we can''t enter the calling fcuntion loop:
if (checkValid(in, first))
{
// this code would never get executed?
}




  bool checkValid(std::istream& in, std::string& first){    std::getline(in, first, '','');    return first == "$FG";}  
It does evaluate to true or false. The line:

return first == "$FG";

returns a bool. The '' first == "$FG" '' part returns true or false and then this bool value is returned by the function. Maybe it will make more sense to you if I add brackets:

return (first == "$FG");

For example, if first does contain "$FG", the std::string comparison will return true and then this true is returned. In this case it would evaluate to this:

return (first == "$FG"); -> return (true);

[ Google || Start Here || ACCU || MSDN || STL || GameCoding || BarrysWorld || E-Mail Me ]
[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || CUJ || MSVC++ Library Fixes || BarrysWorld || [email=lektrix@barrysworld.com]E-Mail Me[/email] ]
Just do this:


  std::string line;std::getline( cin, line );if( line.substr( 0, 2 ) == "FG" ) {  // read it}  


simple and concise
daerid@gmail.com
Hmmm, didn't know about the substr() method. What an idiot I am. So yeah, just do what daerid said.

P.S. Remember to add the string stream extraction into g.valid back into the code:

iss >> g.valid >> g.name >> g.score >> g.age;

[ Google || Start Here || ACCU || MSDN || STL || GameCoding || BarrysWorld || E-Mail Me ]

[edited by - Lektrix on May 26, 2003 5:45:01 PM]
[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || CUJ || MSVC++ Library Fixes || BarrysWorld || [email=lektrix@barrysworld.com]E-Mail Me[/email] ]
Creating a new string with substr isn''t as fast as an in-place compare, though..
inline bool startswith(const std::string& text, const char* start) {  std::string::iterator i = text.begin();  std::string::iterator e = text.end();  while (*start) {    if (i == e || *start != *i) return false;    ++i;    ++start;  }  return true;} 

This topic is closed to new replies.

Advertisement