I Need guidance for Text Extraction (New to C++)

Pages: 123
But how can I include the keywords in the getline function? This seems totally different approach from the >> function.
>> is an operator, getline is a function so their syntax is quite different
So if you have the stream file and the string temp, You should call it this way: getline ( file, temp );
Hi Bazzy,

I have managed to get the outputs out using the getline after assistances from my colleague.

However, I am trying to implement the system to prompt me for the name of the text file before showing the results.

Instead of hardcoding the text file in the system

 
fstream file ( "knowing.txt" );


I have seen a function in a book for an this type of situation but I do not know where to gel in the codes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ifstream* openFile(istream& input)
{
for(;;)
{
// open the file specified by the user
char fileName[80];
cout << “Enter the name of a file” << endl;
// read input from the user in such a way
// that the input can’t overflow the buffer
input.getline(fileName, 80);
//open file for reading; don’t create the file
//if it isn’t there
ifstream* pFileStream = new ifstream(fileName);
if (pFileStream->good())
{
return pFileStream;
}
cerr << “Couldn’t find “ << fileName << endl;
}
return 0;
}



How can I include this to my current codings to replace the ifstream file function?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using namespace std;


string keyword_title = "Title:";
string keyword_director = "Director:";
ifstream file ( "knowing.txt" );
string temp;
int main (int nNumberofArgs, char* pszArgs[])
{
while ( file.good() )
{
    file >> temp;

      if ( temp == keyword_title ) // check the  first keyword word
    {
        getline(file,temp);
        cout << temp + '\n' + '\n';
    }
    if ( temp == keyword_director ) // check the  second keyword word
    {
        getline(file,temp);
        cout << keyword_director + temp + '\n' + '\n';



Please kindly advice if this is do-able. Logically I think it may work. But I still got problems figuring out gelling new codes into mine.
Get a string as usual ( with getline would be better than with >> ) before the declaration of 'file' ( the declaration are better if scoped inside main ).
Then pass as argument of file's constructor thatstring.c_str() instead of "knowing.txt"

eg:
1
2
3
string filename;
getline ( cin, filename ); // get input
ifstream ( filename.c_str() ); // open file, c_str() converts the std::string into a C string ( character array ) 
I think I get what you mean. I will try it out.

I always having problem getting and using the correct functions. My mind is mess up with every functions in C++ I guess.

Thanks for the advice. If it works, I will try to implement them into a class.

Hopefully I can make it work!

Thanks Bazzy!
Hi Bazzy,

I have enter the code but there is no display after i input knowing.txt to the console.

Please advice if I did anything wrong? The rest of the codes remain unchanged.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string filename;
string temp;
ifstream file ( filename.c_str() );


int main (int nNumberofArgs, char* pszArgs[])

{

    cout << "Enter Movie File:";

    getline ( cin, filename );

while ( file.good() )
{
    file >> temp;


I said you should put the declaration inside main. line 3 has to be after line 12
Opps! I am so sorry. I have overlooked on your comments on "( the declaration are better if scoped inside main )."

It works now. Hurray! Now then i understand why it must be declared inside. =)

Now the tough part comes. I am trying to simplified my codes into a class so that I can do a unit testing to it.

Let me try figure it out first how class works.

Thank you for being so patient with all my questions till now.

Hi Bazzy,

Thanks soo much for the advice given. The temp2 in the code was a typo on my part. Sorry about that.

As for the class, ur example is howing me how to declare it using stream but how do i do it when i'm using getline instead? Furthermore, is there any differences if i would want to make a header class, whereby the the execution class cointain the main codes?

Example of a header class:

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <fstream>

using namespace std;

class matchPattern{
public:
void matchPattern();
void string temp();
void string keyword_director();


Please advise.

Thanks in advance
As I explained to flubber there's just some syntax difference between using >> and getline
You can declare the class functions on a header and implement their bodies in a source file as long you link all cpp files ( this is usually done automatically if you are using an IDE )
Notice that the declarations on lines 9-10 are wrong ( void string ) a function can only return 1 type
A good practice is avoiding using directives in headers and adding header guards:
1
2
3
4
5
6
#ifndef MY_HEADER
#define MY_HEADER

// declarations...

#endif 
Dear Bazzy,

I have read up the classes and some of the notes on the requirements of class to my coding.

I logically came out with the following understanding on my own. But I do not know if this is correct theory.

I need your advice if what I intend to declare in the header class and main cpp file is correct.

The more I read, the more I am feel lost. I do not want to go astray from here onwards.


matchPattern.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef _MATCHPATTERN_H
#define	_MATCHPATTERN_H

#include <iostream>
#include <fstream>

class matchPattern {
public:
    matchPattern();
    string keyword_title();
    string keyword_director();
    string keyword_runtime();
    string keyword_plot();
    string keyword_date();
    string filename();
    string temp();
       
//How can include the class with the getline function to the header file?
 getline(file,temp, '(');
 cout << + temp + '\n' + '\n';

};
#endif



Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#include "matchPattern.h"

int main (int nNumberofArgs, char* pszArgs[])

{
    cout << "Enter Movie File:";
    getline ( cin, filename );
    ifstream file ( filename.c_str() );

while ( file.good() )
{
    file >> temp;
     if ( temp == keyword_runtime ) // check the  first keyword word
    {
  //How can I call my class to output my getline and how to inform the string that my keyword is "Runtime:"
    }
    if ( temp == keyword_director ) // check the  first keyword word
    {
  //How can I call my class to output my getline and how to inform the string that my keyword is "Director:"
    }

Last edited on
Notice:
- string keyword_title(); & similar are declaring functions
- You cannot call code from the class body, you need to put it in a member function.

(simplified) example of what I think you should have:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Header
class matchPattern { // the name of the class seems that you shouldn't look for specific keywords in the file but they should be given by the user, anyway I'll just show you how to get the 'Director' stuff
     public: // everything is public to be simpler
        std::string director, keyw_dir; // member variables
        friend istream & operator >> ( istream &, matchPattern & ); // already explained in previous posts
        friend ostream & operator << ( ostream &, const matchPattern & ); // already explained in previous posts
        matchPattern ( ) : keyw_dir ( "Director:" ) {} // the constructor is so small you can leave it in the header or move in the source file if you prefer
};
// Forward declaring the friend operators
istream & operator >> ( istream &, matchPattern & );
ostream & operator << ( ostream &, const matchPattern & );
___________________________________________________________________
// Source
istream & operator >> ( istream &is, matchPattern &mp )
{
    string temp; // local variable
    while ( is.good() )
    {
        // everything is as before just 'file' is called 'is' (from the function parameter) and you have 'mp.' before the class members
        is >> temp;
        if ( temp == mp.keyw_dir )
           getline ( is, mp.director );
    }
}
ostream &operator << ( ostream &os, const matchPattern &mp )
{
    // as you were doing with cout
    os << "The director is " << mp.director;
}
___________________________________________________________________
// Main source
int main()
{
     matchPattern myMatchPattern; // declare a class object
     string filename;
     // get filename...
     ifstream file ( filename.c_str() );
     file >> myMatchPattern; // here you are using your own overload of the >> operator
     cout << myMatchPattern; // << operator
}


BTW are you and wanthor 2 different people ?
Hi Bazzy,

Yes, wanthor and I are 2 different people. But we are frends. I ask him to join this forum because I told him that I have found alot of tips and guidance from you.

Tulang also our friends. We are all C++ beginners.

Hi Bazzy,

I have a situation here and need your advice. I have found out that when I used a getline function, the extracted value that was retrieved have extra characters inside.

For example, Director: Alex Tyson

If I used the getline, the temp will show a value of "Alex Tyson//r" and not "Alex Tyson" purely.

Can you advice how can i remove the hidden //r character from the string?

I need to remove this as I need to do a test stating that temp == "Alex Tyson" is true.

But as they still detect as "Alex Tyson//r" == "Alex Tyson", it always shows as false.



1
2
3
4
5
6
file >> temp;

if ( temp == keyword_director ) // check the  first keyword word
    {
        getline(file,temp);
        cout << keyword_runtime + temp + '\n' + '\n';
That's the Microsoft end of line encoding. Instead of having just a \n it has both \r and \n
so use getline( stream, string, '\r' ); and discard the following \n character
Hi Bazzy,

Does this affect on Linux Platform? It show the same error even I put this.

1
2
3
4
5
6
7
8
9
10
11

                    file >> memory_keyword;

                    if ( memory_keyword == request_keyword )

                    {

                        getline(file,memory_keyword, '\r');

                        CPPUNIT_ASSERT( memory_keyword == "Alex Proyas" );
Usually Unix-like OS use \n see http://en.wikipedia.org/wiki/Newline#Representations
If you want your program to be portable you may need to make your own getline function:
1
2
3
4
5
6
7
8
9
yourgetline pseudocode ( parameters = istream&, string& )
declare a char
while the char != \r or \n
   istream.get the char
   append the char to the string
if the char == \r
peek next char
if char == \n
   remove it from the string
Sorry Bazzy,

But I do not know what you mean with the pseudocode.

You mean I need to redo my getline code?

 
getline(file,memory_keyword);
Last edited on
Hi bazzy,

Is there anyway that i can simplify these codes?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{

                file >> strMemKey;

                if ( strMemKey == strReqKey )

                {

                    getline(file,strMemKey);
                    getline(file,strMemKey);
                    getline(file,strMemKey);

                    return strMemKey;

                }

            }


As you can see i have three getlines. Is there anyway i could simplify it with one line of code?
You need to define your getline function to work with any new line character sequence.
If you prefer here is actual code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void getline ( istream &is, string &str )
{
    char c;
    while(true)
    {
        is.get ( c );
        if  ( c == '\n' || c == '\r' || !is.good() )
            break; // exit from while block
        str.push_back ( c ); // add c to str
    }

    if ( c == '\r' && is.peek() == '\n' ) // Microsoft encoding ( \r\n )
      is.get();// remove \n
  
}



[Edit] For the last question: No, AFAIK getline is the shorter way and it could read just one line per call
Last edited on
Topic archived. No new replies allowed.
Pages: 123