trying to get"random"line() from a txt file

I have been using this forum as a wonderful reference tool for several months now, and I have to say, this is my first post.

I am a college student and am taking my first C++ class. In the class we have just started working on File I/O.

I have already read five to six chapters ahead and have a basic understanding of the material I have covered on my own.

My question then:
Introduction

I am attempting to create a "card game" where there are two different decks, one containing 91 cards and the other 465.
I need to generate code that will create a random number, use that number to pull a line from one of four .txt files based upon the number, and then not use that number/line again.
This needs to happen once for each deck, and then repeat the process until there are no more cards, or the user wishes to quit.

Problem

I am not too familiar with how to set up an array, or if I even need to use one.
I cannot get the loop that I am using to repeat with a NEW random number.
I cannot associate a random number to a corresponding .txt file line.
My professor suggested "Just make an array and setup a random number to come up only once [sic] by allocating a specific variable to it."
I don't have a clue what my professor even means by that, and when she saw the game, she said she will not help me any more.
I have a friend who has a degree in CompSci, but he hasn't returned an email in weeks.
I am frustrated

Conclusion

I cannot post the content of the cards as per the "Terms of Agreement" for this site.
I have searched this site, as well as the entire interwebs to no avail. (could just be my lack of understanding)
I also know from the many threads I have read, "system("pause")" is bad and creates security problems. ;)

I humbly request assistance.

Brandon

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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//Cards Against Humanity


#include <iostream>		
#include <iomanip>		
#include <string>		
#include <algorithm>	//dunno - unless i really need an array, but don't know how to utilize array properly... 
#include <fstream>		
#include <cstdlib>		//dunno
#include <vector>		//dunno
#include <ctime>		//dunno - unless used with time... but don't know if i need that even
using namespace std;

	int myrandom (int i)	{ return std::rand()%i;}	//dunno

	int main()
{
	#define ALPHA 10	//only for array?
	#define OMEGA 10	//only for array?

	ifstream CahPlay1;	//need v
	ifstream CahPlay2;	
	ifstream CahPlay3;	
	ifstream CahNames;	//need ^

                //files
	CahPlay1.open("CardsPlace1.txt");
	CahPlay2.open("CardsPlace2.txt");
	CahPlay3.open("CardsPlace3.txt");
	CahNames.open("CardsNames.txt");
	
		//variables
	int draw, place;
	double height;
	string play1;
	string play2;
	string play3;
	string playX;
	string card;
	string again;
	string cah[ALPHA][OMEGA];
	string n, m, g;
	int seed;

	seed = time(0);	//dunno
	srand(seed);
	
		//randomNum = 1 + rand() % maxRange;
	draw = 1 + rand() % 465;
	place = 1 + rand() % 91;
	play1 = 1 + rand() % 78;
	play2 = 1 + rand() % 11;
	play3 = 1 + rand() % 2;
	playX = play1, play2, play3;
	n = 1 + rand() % 465;
	m = 1 + rand() % 465;
	g = 1 + rand() % 465;
	n != m, g;
	m != g;
		
		//doesn't really work
	ifstream P("CardsNames");
	string play;
	getline(CahPlay1, play1);
	getline(CahPlay2, play2);
	getline(CahPlay3, play3);

	cout << play1 << endl;
	P.close();

	system("pause");

	cout << "Cards Against Humanity (C++ Version)\n\n";

	system("pause");

		//do-while works, but no file grab or repeat of new random just repeat of same "random"
do
	{
		cout << "\n\nThink of a number between 1 - 91 and ";
	system("pause");
		cin >> place;
		if ((place <= 78) || (place != 0))
		{	getline(CahPlay1, play1);
		cout << play1 << endl; }
		else if ((place <= 89) || (place >= 79))
		{	getline(CahPlay2, play2);
		cout << play2 << endl; }
		else if ((place = 90) || (place = 91))
		{	getline(CahPlay3, play3);
		cout << play3 << endl; }

	/*while (playX <= 465)
	{
		getline(CahNames, card);
		cout << card << endl;
	}*/
		cout << "\n\nThink about how you would answer the question as you ";
	system("pause");
		cin >> place;
		if ((place <= 78) || (place != 0))
		{	getline(CahPlay1, play1);
		cout << n << endl; }
		else if ((place <= 89) || (place >= 79))
		{	getline(CahPlay2, play2);
		cout << n << m << endl; }
		else if ((place = 90) || (place = 91))
		{	getline(CahPlay3, play3);
		cout << n << m << g << endl; }

	system("pause");
		//cout << "
		cout << "\n\n\nWould you like to try again? (Y/N)\n";
		cin >> again; 
	}
	while ((again == "Y") || (again == "y"));

	CahPlay1.close();
	CahPlay2.close();
	CahPlay3.close();
	CahNames.close();

		//was supposed to help, but don't know how... thanks internet! U_U
/*
	std::srand ( unsigned ( std::time(0) ) );
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<465; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

  // using built-in random generator:
  std::random_shuffle ( myvector.begin(), myvector.end() );

  // using myrandom:
  std::random_shuffle ( myvector.begin(), myvector.end(), myrandom);

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';*/

	          //I'm not sure if this is right OR if I even need it
	// make an array and [random number generator]
	/*
	for (n=0;n<ALPHA;n++)
    for (m=0;m<OMEGA;m++)
    {
      cah[n][m]=(n+1)*(m+1);
    }*/
  return 0;
}
> I am not too familiar with how to set up an array

First read up on std::vector<>
http://www.mochima.com/tutorials/vectors.html


> was supposed to help, but don't know how... thanks internet! U_U

Let us say, we want to 'generate code that will create a random number, use that number to pull a line from a text files based upon the number, and then not use that number/line again. And then repeat the process until there are no more lines'

One way to do this would be:
a. read all the lines in the file into a std::vector<>
b. then shuffle the lines in the std::vector<> to generate a random permutation of these lines.
c. and finally access the random permutation of lines one by one.

This is what the code you found on the internet was doing.

More or less the same code, annotated:
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
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>

int main()
{
    std::srand( std::time(0) ) ; // seed the rng

    const char* const path2file = __FILE__ ; // file name; in this example, this file
              // replace __FILE__ with the path to the actual file eg. "CardsPlace1.txt"

    // read the file line by line into a vector
    std::ifstream file(path2file) ; // open the file
    std::vector<std::string> lines_in_file ; // put the lines in the file into this

    std::string line ;
    while( std::getline( file, line) ) // for each line in the file
         lines_in_file.push_back(line) ; // add the line to the vector

    // at this point, 'lines_in_file' contains the lines in the file
    // in the order that they were read
    // lines_in_file[0] is the first line that was read
    // lines_in_file[1] is the second line that was read
    // ...
    // lines_in_file[ lines_in_file.size() - 1 ] is the last line that was read

    // now, rearrange the lines in the vector in  random order
    // by shuffling the lines like one would shuffle a pack of cards
    std::random_shuffle( lines_in_file.begin(), lines_in_file.end() ) ;


    // and once that is done,
    // lines_in_file[0] contains a random line from the file
    // lines_in_file[1] contains another random line from the file
    // etc.

    // to 'pull a random line from the file, and then not use that line again'
    // we can just iterate through the vector, first 'pulling' lines_in_file[0],
    // then lines_in_file[1] ans so on till the end

    // print out the lines in the random permutation one by one
    // this permutation contains lines in the file in random order:
    for( std::size_t i = 0 ; i < lines_in_file.size() ; ++i )
          std::cout << lines_in_file[i] << '\n' ;
}
Thank you for the reply, I am sorry that it has taken me so long to respond. I am very busy atm, and this little project has been set aside several times now.

One question:
Am I correct in assuming that the "std::" before all of your commands is just redundant? Or is it necessary?
that the "std::" before all of your commands is just redundant?

Its denotes the full name of a function. Its like a path prefix of a file. To avoid it you could declare all std::names before using them like:

1
2
using std::size_t;
using std::cout;


Then f.e. the final loop could be rewritten as:

1
2
for( size_t i = 0 ; i < lines_in_file.size() ; ++i )
      cout << lines_in_file[i] << '\n' ;
Topic archived. No new replies allowed.