I have a line in a .txt file that starts with the word "Words". What I am trying to do now is for the example below to find all the words after "Words" that is before a "(" wich in this case is "One" and "Two". As seen they are separated by ",".
One important notice here is that you never know how many it can be but a maximum of 6 words. So it could ex also be One(1), Two(2), Three(3).

What technique could be used to find these in the Line that start with "Words"

Words: One(1), Two(2);

Recommended Answers

All 8 Replies

Something like this might work: you need std::string with its find() and substr() methods.

read the entire word into one std::string object
start loop
locate a comma
use std::string's substr() to extract the word from position 0 up to the comma
now use std::string's find method to see if it contains a '(' character
if it does, then increment a counter
end of loop

if you want to do some spirited programming ( http://www.boost.org/libs/spirit/index.html )

#include <boost/spirit/core.hpp>
#include <boost/spirit/actor.hpp>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
using namespace boost::spirit;

bool parse_line( const char* cstr, vector<string>& words )
{
  subrule<0> top ;
  subrule<1> word ;

  return
     parse( cstr,

            //  begin grammar
            (
              top = str_p("Words:")
                           >> word >> *( ',' >> word )
                           >> ';' ,

              word = (+alpha_p)[ push_back_a( words ) ]
                           >> '(' >> digit_p >> ')'
            )
            ,
            //  end grammar

            space_p ).full ;
}

int main()
{
  string str[] =
  {
    "Words: One(1), Two(2);",
    " not words",
    "Words: boost(1), and(2), spirit(3), rule(4) ;",
    "Words: parse(1) fails(2), no(3), comma(4) ; ",
    "Words: parse(1), fails(x), wrong(3), digit(4) ; ",
    "Words: this(1), line(6), should(2), be(3), quite(4), ok(5) ;",
    "Words: parse(1), fai+ls(2), not(3), alpha(4) ; ",
  } ;
  for( size_t i=0 ; i < sizeof(str)/sizeof(*str) ; ++i )
  {
    vector<string> words ;
    if( parse_line( str[i].c_str(), words ) )
    {
        cout << "line " << i << " : " ;
        for( size_t i=0 ; i<words.size() ; ++i )
           cout << words[i] << ' ' ;
        cout << '\n' ;
    }
  }
}
[B]> g++ -Wall -std=c++98 -pedantic -Werror -I /usr/local/include parse_it.cc && ./a.out[/B]
line 0 : One Two
line 2 : boost and spirit rule
line 5 : this line should be quite ok

I am trying out the technique with find(), substr() etc...
I am not sure how to begin but my first goal I beleive should be for the row:

Words: One(1), Two(2);

To first put the whole row into a std::string and then se if this std::strings starts with the Word: "Words:".
I have tried out something like this:

while ( getline(Read, Line, '\n') )
	{	
		
	     Words2 = Line.substr(Line.rfind(":") + 1);
	     Read.get();

	     Out << Words2  << '\n';
	}

However I know what this function is doing. It substrings the Line so "Words:" ´dissapear´.
How will it be possible to instead keep the word: "Words:".
If I can keep that in a std::string then I know I have reached the right line.
Thanks

string Words2;
while ( getline(Read, Line, '\n') )
{
      if( line.find("Word:") == 0) 
      {
           Words2 = Line.substr(Line.rfind(":") + 1);
      }
}

Yes this did work. What I now have is this:

std::string Contents1 = "One(1), Two(2);"

What I want to do is to find all words that is before a "(" and put each to a separate std::string.
What technique is used for this. I beleive find will be used for it but dont know exactly how to exctract out "One" and "Two" ?
One important thing is that I dont know how many words it can be. It can be a maximum of 6 words. In this case it is 2 words, One and Two.

string Words2;
while ( getline(Read, Line, '\n') )
{
      if( line.find("Word:") == 0) 
      {
           Words2 = Line.substr(Line.rfind(":") + 1);
      }
}

Go here: http://www.cppreference.com

Look for C++ Strings and go to that page.

Look up find(), substr(), erase(), and anything else that might look useful.

Use whatever combination of methods seem to work, say maybe a loop within which is a call to find followed by a call to substr() followed by a call to erase().

Alternatively, if you feel uncomfortable using what's in STL (or Boost or whatever else you can locate), then you could alwarys write your own parsing function. It's actually quite a learning experience, though so is learning how to manipulate the STL containers or learning how to use the Boost library, so it's your choice.

I am still truly stuck of how to extract "One" and "Two" from this string.
It is the first time I do it and the examples doesn´t tell this scenario because it is the contents before each "(" that I am after and these will be put to a separate std::string.
Thanks

std::string Contents1 = "One(1), Two(2);"

I can't test the following since I don't have a compiler handy. The following needs to be fleshed out with conditionals and looping to do what you want, but the basic protocol will remain.

/*one version of find() returns the numerical location of the first element in the string if found and npos if not found*/
int stop = Contents1.find('(');

/*one version of substr() takes two parameter, the first being where to start and the second being where to stop, both being numerical types*. It returns a string/

string temp = Contents1.subt(0, stop);
cout << temp;

/*one version of erase takes two parameters, one being where to start, the other being how many char to erase, both of which are numerical values. It returns a string reference*/

Contents1.erase(0, stop);

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.