How to grab random line from a .txt file?

Hello there, I am struggling with figuring out how to grab a single line from a .txt file at random. The .txt file has 20 lines and each line has a name, essentially a string. In my main code I can open the .txt file but all lines come through not just one. The reason behind all of this is from an assignment where I grab that random word from the .txt file then insert that "name" into my guessing game where the user has limited amount of tries to guess the word. Below is the code of the guessing game which does work but, now I need to add that extra of having a random word pulled from a .txt file and have the user guess that new word.
Thank you to anyone who goes out of their way to try and help!

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include <ctime> 

using namespace std;

void display(vector<char>ans);
bool checkGuess(vector<char>ans, char guess);
void revealLetter(char guess, vector<char>&ast, vector<char>ans, int &revealed);
vector<string> getWords(string fileName);
void printWords(vector<string>words);

int main()
{
	string fileName = "list.txt";
	vector<string>words = getWords(fileName); //ifstream is in getWords

	vector<char>ans{ 's', 'l', 'e', 'e', 'p' };//this needs to be replaced with a random word from the .txt file
	vector<char>ast{ '*', '*', '*', '*', '*' };//this somehow needs to stay, trying to figure that out as well

	int guesses = 10;
	int revealed = 0;
	char guess;

	cout << "Guess the word!" << endl;
	while (guesses>0)
	{
		cout << "You have " << guesses << " guesses left" << endl;
		display(ast);
		cout << "Guess a letter :" << endl;
		cin >> guess;

		if (checkGuess(ans, guess) == true)
		{
			cout << "You revealed a letter!" << endl;
			revealLetter(guess, ast, ans, revealed);
		}
		if (revealed == ans.size())
		{
			cout << "You win" << endl;
			cout << "GAME OVER" << endl;
			break;
		}
		guesses--;
	} //end of while loop
	if (revealed != ans.size())
	{
		cout << "How could you not get this?" << endl;
		cout << "GAMEOVER" << endl;
	}
	return 0;
}

void display(vector<char>ans)
{
	for (int i = 0; i<ans.size(); i++)
	{
		cout << ans[i];
	}
	cout << endl;
}

bool checkGuess(vector<char>ans, char guess)
{
	for (int i = 0; i<ans.size(); i++)
	{
		if (guess == ans[i])
		{
			return true;
		}
	}
	return false;
}

void revealLetter(char guess, vector<char>&ast, vector<char>ans, int &revealed)
{
	for (int i = 0; i<ans.size(); i++)
	{
		if (guess == ans[i])
		{
			ast[i] = guess;
			revealed++;
		}
	}
}

vector<string>getWords(string fileName) //fills the vector from main
{
	vector<string>words;
	ifstream file;
	string word;

	file.open(fileName);

	while (file >> word)
	{
		words.push_back(word);
	}
	file.close();

	return words;
}

void printWords(vector<string>words) //prints "list.txt" randomly
{
	srand(time(0));

	for (int i = 0; i < words.size(); i++)
	{
		cout << words[rand() % words.size()] << endl;
	}
}  
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
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <iterator>
#include <random>
#include <iomanip>

std::vector<std::string> get_words( std::istream& stm )
{
    // https://en.cppreference.com/w/cpp/iterator/istream_iterator
    // http://www.stroustrup.com/C++11FAQ.html#uniform-init
    return { std::istream_iterator<std::string>(stm),
             std::istream_iterator<std::string>{} } ;
}

std::string random_word_from_file( const std::string& file_name )
{
    // https://en.cppreference.com/w/cpp/numeric/random
    static std::mt19937 rng( std::random_device{}() ) ;

    std::ifstream file(file_name) ;
    const auto words = get_words(file) ;
    if( words.empty() ) return {} ;

    // https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
    std::uniform_int_distribution<std::size_t> distrib( 0, words.size() - 1 ) ;
    return words[ distrib(rng) ] ;
}

int main () // usage example
{
    const std::string path = "/usr/share/common-licenses/LGPL-3" ;
    std::cout << std::quoted( random_word_from_file(path) ) << '\n' ;
}

http://coliru.stacked-crooked.com/a/ce41d41e27ae9476
Last edited on
@JLBorges, It should be words.size() - 1 for the max of the distribution.
Yes, thanks! Correcting it now.
Thanks for the help!
Topic archived. No new replies allowed.