Generate certain number of questions

The objective is to generate however number of questions the user wants. The questions and answers both need to be between 0 and 100. I've run this program several times, and sometimes the objectives seem filled, other times I'll get answers/question values over 100, or the number of questions will be less or greater than desired.

I've tried adding more if/while statements, but just when I think I've got it down, several runs later I'll have the same issue. Any ideas how to fix this?


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
#include <iostream>
#include <cstdlib>      // rand() function
#include <ctime>        // time
using namespace std;

int main()
{
    int numQ;      // number of questions
    int ans;       // answer
    
    cout << "\t\tWelcome to 3rd Grade Math Tutor!\n" << endl;
    cout << "Enter number of questions desired: ";
    cin >> numQ;
    cout << endl << endl;
    cout << "Enter -1 to exit at any time.\n" << endl; 
    
    
    // DISPLAY QUESTIONS
    for (int i = 0; i < numQ; i++)   // iterate numQ # of times
    {
         // RANDOM NUMBERS EVERY RUN
         unsigned seed;       // positive #'s only
         seed = time(0);
         srand(seed);
         
         int num1 = rand()%100 +1;   // Number 1; max 100
         int num2 = rand()%100 +1;   // Number 2; max 100
         
         int numAns = num1 + num2;    // numAns
         
         // REGENERATE NUMBERS
         while (numAns > 100)        // regenerate #'s if numAns > 100
                                     // WHEN CHANGED TO 'IF' WORKS KIND OF
         {
               int num1 = rand()%100 +1;   // Number 1; max 100
               int num2 = rand()%100 +1;   // Number 2; max 100
         
               int numAns = num1 + num2;    // numAns
               
               if (numAns < 100)           // If new #'s within range
               {
                          cout << num1 << " + " << num2 << " = ";
                          cin >> ans;
                          cout << endl;
                          i--;
                          break;       // numQ does not taike these q's
                                       // into consideration in counting
                          
               }
         }
         
         cout << num1 << " + " << num2 << " = ";
         cin >> ans;
         cout << endl;
         
         // QUIT
         if (ans == -1)
         {
                 break;
         }
         
    }
            
               
return 0;
}
Hello nadia102,

As a start loose lines 22 and 23 then move line 24 above the for loop. By calling "srand()" with each iteration of the for loop you are likely using the same number for the seed and even if the time changes you are using different starting places for "rand()". This may be working, but is causing the problems that you are seeing.

You only need to call "srand" once in a program and if you write it this way you cover everything without extra code. srand(static_cast<size_t>(time(nullptr)));.

I have also found this video to be helpful in understanding the problems with "rand". https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

As for the rest of the program I will load it up and give it a test.

Andy
Hello nadia102,

After testing the program this is what I found.

In the for loop you define and set these variables:
26
27
28
29
int num1 = rand()%100 +1;   // Number 1; max 100
int num2 = rand()%100 +1;   // Number 2; max 100
         
int numAns = num1 + num2;    // numAns 

This is fine as with each iteration of the loop you define and set each variable.

But in the while loop you define and set these variables again. The problem is that they become local to the while loop and are lost when the while loop ends never affecting the variables defined in the for loop. Remove the int and just use the variables defined in the for loop.

The while lop is fine, but all you need for the if statement is:
40
41
42
43
44
45
46
47
48
if (numAns < 100)           // If new #'s within range
{
	//cout << num1 << " + " << num2 << " = ";
	//cin >> ans;
	//cout << endl;
	//i--;
	break;       // numQ does not taike these q's
					// into consideration in counting
}

Using line 45 this will cause an endless loop as "i" will never reach or exceed "numQ".

This part I added just for fun:
1
2
3
4
5
6
7
8
if (numAns == ans)
{
	std::cout << "\n  That is correct.\n\n";
}
else
{
	std::cout << "\n    Incorrect answer.\n\n";
}

In the if statement you could add a counter for correct answers for later use outside the for loop.

Andy

Edit:
Last edited on
Thank you so much!
Hello nadia102,

You are very welcome.

Now that you should be done I offer this as one suggestion and what I did. The comments should explain things. If not let me know.

Do not rely on using the "\t". It does not always work the way that you want. Using the "std::string" the way I did or "std::setw()" from the "iomanip" header file does much better at spacing than the "\t", but the "\t" still has its uses.

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
#include <iostream>
#include <iomanip>  // <--- Added.
#include <limits>   // <--- Added.
#include <string>   // <--- Added.

#include <cstdlib>      // rand() function
#include <ctime>        // time

using namespace std;  // <--- Best not to use.
// A recent post that is worth reading. http://www.cplusplus.com/forum/beginner/258335/

int main()
{
	// <--- Always a good idea to initialize your variables.
	int numQ{};      // number of questions
	int ans{};       // answer
	int corrAns{}, i{}; // <--- Define "i" outside the for loop for later use.

	cout << std::string(16,' ') << "Welcome to 3rd Grade Math Tutor!\n" << endl; // <--- Using "string" this way replaces the "\t"s.
	cout << "Enter number of questions desired: ";
	cin >> numQ;

	cout << endl << endl;
	cout << "Enter -1 to exit at any time.\n" << endl;

	srand(static_cast<size_t>(time(nullptr)));

	// DISPLAY QUESTIONS
	for (i = 0; i < numQ; i++)   // iterate numQ # of times. Defining "i" here makes it local to the for loop.
	{
		// RANDOM NUMBERS EVERY RUN

		int num1 = rand() % 100 + 1;   // Number 1; max 100
		int num2 = rand() % 100 + 1;   // Number 2; max 100

		int numAns = num1 + num2;    // numAns

		// REGENERATE NUMBERS
		while (numAns > 100)        // regenerate #'s if numAns > 100
									// WHEN CHANGED TO 'IF' WORKS KIND OF
		{
			num1 = rand() % 100 + 1;   // Number 1; max 100
			num2 = rand() % 100 + 1;   // Number 2; max 100

			numAns = num1 + num2;    // numAns

			if (numAns < 100)           // If new #'s within range
			{
				//cout << num1 << " + " << num2 << " = ";
				//cin >> ans;
				//cout << endl;
				//i--;
				break;       // numQ does not taike these q's
								// into consideration in counting
			}
		}

		cout << num1 << " + " << num2 << " = ";
		cin >> ans;
		//cout << endl;

		// QUIT
		if (ans == -1)
		{
			break;
		}

		if (numAns == ans)
		{
			std::cout << "\n  That is correct.\n\n";
			corrAns++;
		}
		else
		{
			std::cout << "\n    Incorrect answer. The correct answer is " << numAns << "\n\n";
		}
	}

	std::cout << std::fixed << std::setprecision(0);

	std::cout << "\n Out of " << i << " questions you got " << corrAns << " correct. For "
		<< ((static_cast<double>(corrAns) / static_cast<double>(i)) * 100.0) << "%\n";

	// A fair C++ replacement for "system("pause")". Or a way to pause the program.
	// The next line may not be needed. If you have to press enter to see the prompt it is not needed.
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
	std::cout << "\n\n Press Enter to continue: ";
	std::cin.get();

	return 0;	
}


Andy
Topic archived. No new replies allowed.