Reading in several lines from a text file at once

I'm trying to write a quiz program which selects 5 lines from a text file and cout them to the screen. I have a text file with questions in it, with each question consisting of 5 lines followed by a blank line to make the text file easier to read.

So far, I've been able to call the first 5 lines to the screen, but I can't skip through the questions. I've added a cout command to display the line numbers being called, and this displays the expected line numbers, but the lines of text from the text file aren't displayed. Does anyone have any ideas why this is? I thought the problem may lie within the while loop but considering the fact that the line numbers are displayed it may be an issue with the if statement.

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

using namespace std;

int main()
{
        
		
	int x = 0;  		//Integer to select question
	int i = x+5;
	ifstream file("history.txt");		
	string line;
	unsigned int line_number(0);		//sets first line number to 0
	unsigned int requested_line_number(x);
		
	
		while (getline(file, line))
	   	{
			if(x<i)
			{	 
				if (line_number == requested_line_number)
				{
					cout << line << "\n";
				}	 	 	 
				line_number++;
				requested_line_number++;
				x++;
				cout << requested_line_number << endl;
			}
		}
	
}


I couldn't find anything like this on here and apologise if I'm repeating someone else's problem. Any help would be appreciated, Thanks in advance.
Last edited on
You'll want to read in the entire file at one time, store the contents in an array or vector, and then randomly shuffle or select an item.

something like this might work:
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
class Question
{
    std::string q;
public:
    Question(std::istream& in)
    {
        for (int i = 0; i < 5; ++i)
        {
            std::string Line;
            getline(in, Line);
            q.append("\n");
            q.append(Line);
        }
    }
    friend std::ostream& operator<<(std::ostream& out, Question& question);
};

std::ostream& operator<<(std::ostream& out, Question& question)
{
    out << question.q;
    return out;
}

int main()
{
    std::vector<Question> Qlist;
    std::ifstream fin("history.txt")
    while(fin.peek() != std::traits::eof())
        Qlist.push_back( Question(fin) );

    std::random_shuffle( Qlist.begin(), Qlist.end() );

    for(std::vector<Question>::iterator it = Qlist.begin(); it != Qlist.end(); ++it)
        std::cout << *it;
}
Last edited on
Thanks for the reply. I have to say some of that went a little over my head though. I'm not too familiar with creating new classes so I'll need to look up on that. Having said that It'll give me a new direction to work in which hopefully will work better :)

I can get most of it to work but there is an issue with the while loop on line 28. I get an error message saying
'std::traits' has not been declared.
I'm not sure if this is because i'm missing a header file or not as I'm not entirely sure what's happening inside the brackets of while loop.

Thanks again
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <fstream>
#include <string>

// print out a question from a file,
// with each question consisting of 5 lines followed by a blank line
void print_question( const char* path_to_file, int question_num )
{
    enum { LINES_PER_QUESTION = 6 } ;
    if( question_num < 1 ) return ;

    std::ifstream file(path_to_file) ;
    std::string line ;

    // skip lines till we get to the question
    int lines_to_be_skipped = (question_num-1) * LINES_PER_QUESTION ;
    for( int i = 0 ; i < lines_to_be_skipped ; ++i ) std::getline( file, line ) ;

    // print it out along with the blank line at the end
    for( int i = 0 ; i < LINES_PER_QUESTION  && std::getline( file, line ) ; ++i )
        std::cout << line << '\n' ;
}
The ideas so far are based upon the fixed number of lines per question.

Here's an alternative, which instead uses the blank line between questions in order to break up the file into separate questions. That permits short questions, consisting of a single line, or questions with more than five lines if required.
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>

    using namespace std;

int readQuestions(vector<string> & quest, char * fname);

int main()
{
    srand(time(0));

    vector <string> questions;

    int  numQ = readQuestions(questions, "input.txt");

    // List the entire contents of the vector.
    for (int i=0; i<numQ; i++)
    {
        cout << questions[i];
        cout << "\n---------------------------------------" << endl;
    }

    // Display a randomly-chosen question.
    if (numQ > 0)
    {
        int n = rand() % numQ;
        cout << "________________________________\n"
             << questions[n]
             << "\n________________________________" << endl;
    }

    return 0;
}

int readQuestions(vector<string> & quest, char * fname)
{
    ifstream fin(fname);
    string line;
    string question;

    while (getline(fin,line))
    {
        if (line != "")
        {
            if (question.size())
            {
                question += '\n';
            }
            question += line;
        }
        else
        {
            if (question.size())
            {
                quest.push_back(question);
                question = "";
            }
        }
    }

    // if the file did not end with a couple of blank lines,
    // there may be one last question to be stored.
    if (question.size())
    {
        quest.push_back(question);
    }

    return quest.size();
}


Lines 19 to 33 are simply for testing purposes, to show that something was read.
If there was a problem, numQ will be zero, hence the test at line 27.
Last edited on
Thanks for all the replies, I should have enough to get it working now. I'll try a few of these ideas out and see if they do what I need them to. Thanks again for your help :)
Topic archived. No new replies allowed.