Extracting specific lines of text from a text file

Hi,

I have posted a similar question before based on richTextBoxes and windows forms app:http://www.cplusplus.com/forum/windows/138373/

Some C++ users gave me some directions where to find some information but I'm having trouble getting any success. So I thought I would simplify my question and go back to C++.

I have a text file called (Test.txt) with the following text:

This is line one
This is line two
This is line three

How do I go about writing a program that will print a line of text (e.g. "This in line two" on the console screen?

All I can seem to do is display the entire text file.

Could someone PLEASE provide an example code? I would very much appreciate it!
Thanks,
e.g. "This in line two"

What are your criteria for selecting which line you want to display? e.g. the 2nd line, or any line containing the letter "w", or some random line etc.

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
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

bool isWanted(const std::string & line);

int main()
{
    ifstream fin("Test.txt");
    
    string line;
    while (getline(fin, line))
    {
        if (isWanted(line))
            cout << line << endl;
    }
    
    return 0;
}

bool isWanted(const std::string & line)
{
    // any selection criteria you like
    return (line.find("two") != string::npos);
}
Last edited on
Thanks for the reply Chervil,

The actual program that I'm working on is a windows form app. Currently, the text that appears in the program's richTextBoxes (there's a lot of them) are within the program and can only be altered by using Visual C++ etc. I would like the program to run by accessing the text externally. I.e. within one or more text files. However, I would like a line, or lines of text, within a text file be assigned a specific richTextBox. This means that an administrator could change these lines of text when needed via a text editor, not by editing the code. I hope this makes sence.

N.b. I know that I'm asking a questiong that should / could be in the windows forum but I want to understand the C++ coding. Then I can adapt this to C++ / CLI.

So, I thought that I could try and understand how to do this at a foundational level. I.e. a simple task as described in my original post. I can load txt files into richTextBoxes and save them. But I'm having trouble calling specific lines of text within a text file.

I also thought that if each line of text was numbered, it might be easy to then call that line when needed. E.g.

TextFile.txt:
001 This is line one
002 This is line two
003 This is line three

Your code Chervil works well! Thanks for this. But how could I do what you have suggested but exclude the line number (e.g. 001) at the beginning?

I hope this makes sense and I REALLY apprecate your help. I've been batteling this for some time.
Last edited on
Hi all,

I have solved my last post with the help of Chervil's example code. It was a very simple addition using 'string substr'. This is the code that solves my second question.

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
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

bool isWanted(const std::string & line);

int main()
{
    ifstream fin("Test.txt");
    
    string line;
    while (getline(fin, line))
    {
        if (isWanted(line))
        cout << line.substr(4) << endl;  // this is where string substr is used

    }

    return 0;
}

bool isWanted(const std::string & line)
{
    // any selection criteria you like
    return (line.find("002") != string::npos);
}


Thanks again, Chervil.
I think your approach is ok. When the layout of the text follows a known format, the code can be made more specific. in this case, instead of line.find("002") != string::npos which checks for the text "002" anywhere within the line, you could have line.find("002") == 0 which checks for that text only at the start of the string (that is, position 0).



or the string could be parsed, maybe like this. This may look a little complicated, but the intention is that it would be easier to use:
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
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

using namespace std;

int parseLine(std::string & line);

int main()
{
    ifstream fin("Test.txt");
    
    string line;
    while (getline(fin, line))
    {
        int number = parseLine(line);
        if (number == 2)
            cout << line << endl; 
    }
    
    return 0;
}

int parseLine(std::string & line)
{
    int n = -1;                                 // default value
    if (line.size() >= 3)                       // number in first 3 columns
    {
        std::string first = line.substr(0, 3);  // extract line number 
        std::istringstream ss(first);
        ss >> n;                                // as an integer
        
        if (line.size() >= 4)                   // if rest of line exists
            line = line.substr(4);              // drop first 4 chars from line
        else
            line = "";        
    }
    return n;
}
Hi Chervil,

Thanks again for your time and advice!

I understand your first suggestion, i.e. line.find("002") == 0. As far as I can tell, all lines of text within the actual text file will not have numbers in it, at least like '002'.

Your second suggestion does look better but you're right, it is more complicated to understand. At least for me as I'm still very much a beginner. I'm working on it thought ;).

I made a post on the windows forum because as soon as I made the above improvements and tried them with rtf files (which is needed for my current project), I soon realised that the code will only work with txt files. Rtf files are of course formatted! Nevertheless, I've now learnt some skills that I can use elsewhere so once again, thanks!
Last edited on
One quick suggestion. I would use some sort of existing library to read/write rich text files. Possibly you could use that to generate a temporary text file, or some other temporary store. In other words, decode the rich text and convert it to plain text, and then apply some of the ideas in this thread. Maybe. But I'll leave it at that.
Topic archived. No new replies allowed.