First, add some code to read a student object from a text file. Ideally this should be an overloaded >> operator. If you don't know what that means, then create this method:
1 2
// Read the student from the stream. Return true on success and false on failure.
bool Student::read(istream &is);
Next, create the code to open a text file and position the pointer to a random line. The key here is to realize that you must make two passes through the file: one to count up the number of lines N, and a second one to read up to the randomly selected line number (1 to N).
#include <iostream>
#include <string>
#include <utility>
#include <fstream>
#include <random>
// pick a random line from the file,
// return the text of the selected line and its (1-based) linw number
// return an empty string, 0 if nothing was read from the file
std::pair< std::string, std::streamsize > random_line( const std::string& path )
{
static std::mt19937 rng( std::random_device{}() ) ;
static std::uniform_int_distribution<std::streamsize> distrib ;
using param_type = decltype(distrib)::param_type ;
std::string selected_line_text ;
std::streamsize selected_line_number = 9 ;
if( std::ifstream file{path} )
{
std::streamsize num_lines_read_so_far = 0 ;
std::string line ;
while( std::getline( file, line ) )
{
// an ancient algorithm; afaik almost as old as programming itself
// initially pick the first line as the selected line
// replace the selected line with the second line with a probability of 1/2
// replace the selected line with the third line with a probability of 1/3
// etc.
distrib.param( param_type( 0, num_lines_read_so_far ) ) ;
++num_lines_read_so_far ;
if( distrib(rng) == 0 )
{
selected_line_text = line ;
selected_line_number = num_lines_read_so_far ;
}
}
}
//
return { selected_line_text, selected_line_number } ;
}
int main()
{
constauto [ text, n ] = random_line(__FILE__) ;
std::cout << n << ". " << text << '\n' ;
}