Strange problem with rand(), srand() and...well, random numbers in general ^^'

First of all, thank you all for your hard work guys!

I have a problem here with a console program I'm developing for my fellow students at university (to help us in our anatomy exam)! It should run just on windows systems, though. Anyway, to put it down simply: We're going to attend an exam in quiz-form, so I thought to put all the question we have on our textbook in digital format and build a simple but useful quiz program to learn better and have better results in the exam. Now, speaking of the program: I have created a database of questions from the textbook (around 7 thousand lines of questions, answers and so on), all in the same source file of the program itself (I'm somewhat a lazy person, you know); I have included a few extras, such as a function that randomizes the order in which the questions are presented to the user, as well as the order of the possible answers. The problem is as follows: while I do not find any particulary relevant pattern in the pseudo-random extraction of the question's number, for each run of the program, the pattern of the supposedly randomized order of the possibile answers doesn't simply repeat itself once in a while...it's just FIXED! I have to close the program and click on the .exe file again to make it change!

I've used srand(time(NULL)), but it doesn't seem to work (not in THIS program, at least). Any help?

Here's a condensed version of the code: to test what I'm saying, just press the following sequence of keys:
1, ENTER, 1, ENTER, 5 (or whatever number you want...the smaller the better, trust me ^^), ENTER
At this point you'll be prompted the first question. As a sidenote, the rsq[x] array is the randomsequence the program creates when you chose the path of your first "1" entered as an input. I just displayed it for programming purposes but it will be removed from output as soon as the program is finished ^^. So the question is: why rsq[x] is seems to be fronzen instead of changing every time?

Now the code (which is ready to be compiled. I use Dev-C++, by the way): HERE'S THE LINK (too long for the forum's limitations on characters number):
http://www.mediafire.com/file/w20nzwj1n4q/PQAL_testforum.cpp

THANKS IN ADVANCE FOR ALL YOUR HELP, and for al the help you already gave me in the past!
Last edited on
Next time you want to upload code, use pastebin.

I don't see a single reference to srand().
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <cstdlib>
#include <ctime>

int main(){
    //If you run this program twice in a single second, you'll get the
    //exact same sequence.
    srand(time(0));
    for (int a=0;a<10;a++){
        //Do NOT put srand here.
        std::cout <<rand()<<std::endl;
    }
    return 0;
}
oh, thank you very much for the precious hint!

srand(time(NULL)); is at line 85

here's the new link to the source code: http://de.pastebin.ca/1711283

so...why doesn't it work?
Last edited on
Any clues?
What about it does not work?
int rsq[] should receive 5 new different values every time, but instead its values do not change at all after the first time! I don't understand why!
OK, well I'm unable to trace back all the calls of randomsequence() through that code, but I believe that, in your for loop, you are starting at 1 and then going up to 5, which should cause an error and will not change the first value (0).
randomsequence() is called just once at line 334. The function rquiz() (in which randomsequence() is caled) is called after every user input since it prints the questions of the quiz, the possibile answers, and manages the error check system.
Also, I did not undersand what you said. Could you please explain it a little more extensively?
In your for loop in randomsequence, you start at 1 and continue until the counter is 6, so you cycle through the values 1 to 5. An array of five elements is subscripted 0 to 4, not 1 to 5. 5 is out of bounds.
Edit: by the way you should avoid the use of goto, which is almost always bad programming. It only contributes to the confusing flow of a program without simplifying it noticeably.
And where exactly is the loop that causes rquiz to be called multiple times?
Last edited on
sorry, I got mistaken. rquiz() is called once and it has a for loop inside that calls randomsequence() at every cycle.

Still I don't get your point about randomsequence:

1
2
3
4
5
6
7
8
9
10
void randomsequence (void) {
     for (int i = 1; i < 6; ++i) {
         rsq[i] = 1 + rand() % 5;
         for (int j = 1; j < 6; ++j)
             if (i != j && rsq[i] == rsq[j]){
                        --i;
                        break;
             }
     }
}


i goes from 1 to 5, as expected. The array was declared as an array of 6 elements (like almost all of the arrays in the program) to simplify my life even if I only use the last 5 memory addresses ([1], [2], [3], [4], [5]).

This function here(randomsequence()) is used to be sure there are no repeated random values in rsq[]. Unfortunately, the only time they are randomly generated is the first time randomsequence is called(); for all the following calls to randomsequence() it seems like the values are not changed and therefore remain the same for the rest of the execution, no matter how many times you call randomsequence(). This is what I do not understand.
Last edited on
OK, then declaring that additional element is just a pointless waste of space to simplify something because you don't want to change the numbers to suit the real array? And by repeating the practice, it's even worse, like getting accustomed to using goto. (Another thing you should do whatever you can to remove, especially because I see no good reason to use it instead of respectable control structures in your prog.)
You should get accustomed to the fact that the first subscript of an array is zero, and deal with it. You are wasting compiler energy and space to declare that last unused element so many times when you could reduce both those numbers to show a proper cycling through the array. You should also find a way to work around those gotos in your main, each and every one of them being a cluttering of space and reducing the quality of your code.
Anyway, besides that...
In randomsequence you have a for loop that randomizes the value, and then another for loop with some kind of if statement in it. What does that if statement do?
as I said, the second for loop and the if inside it are needed to be sure rsq[] doesn't contain double numbers (I don't want to have two or three "4" in a sequence of 5 numbers). And example of rsq[] might be:
1, 3, 5, 2, 4.
But not: 5, 4, 2, 4, 2.
Clear?

Regarding the goto statements, and the extra-space in arrays, I really don't care. Usually I don't use gotos, nor do I waste memory space. But I had to write this program in a split second and from scratch without any idea what kind of functions to implement. I've wrote many and many things only on second thoughts, that's why the code looks a bit "patched". I'm not programming this to be a perfect program...I just want it work and I'd like to know where's the problem with rand(). Anyway, thanks for the advices.
I'm going out on a limb here but it may be that you just aren't finding any new values.
Think of it this way. You have five potential values per slot of the array - 1 to 5. you also have five places in the array - 1 to 5 (0 to 4 but I'll play along...).
Let's look at the second execution of this randomsequence. The function looks at it and randomly chooses a value. But in order to satisfy your condition - that every number MUST be different - it will keep on randomizing it until it finds the only number that was not present in any of the other positions of the array- THE ONE IT STARTED WITH.
Because there are only five possible values and five places in the array, the computer will find, every time it randomizes the array, that only one value fits into the given place, and that's the one value that is not in any other number. Therefore, every time it randomizes the array, your error control forces it back to the number it started on.
That's my suspicion. How to solve it is another matter. What I suggest you do is, rather than actually rerandomize that array, just shuffle it. You know each number can only appear once so simply change the order they appear in. Inside a for loop that executes maybe a thousand times, randomly select two elements of your array and swap them around (through a temporary variable of course). That way you won't get this situation. After about a thousand swaps your array should be reasonably random again.
Although I haven't looked at the code in detail, tummychow's suggestion sounds reasonable.

If you just need to shuffle the array, use
std::random_shuffle(array,array+5);

I should note that a shuffle isn't the best randomization method for a quiz. If the person taking the quiz notices it, the last question has a probability of being answered correctly of 1 (ignoring human error).
Last edited on
Man you're a genius! I wrote the algorithm but didn't think of it's consequences! THANK YOU!!

I just added
rsq[i] = 0;
after line 451 (in the for loop that restores the arrays to their default values) and it works wonders! THANK YOU SO MUCHHH!!!
@ Helios: just read your post. Thank your too!
Glad to be of service!
Now for those style issues...
Hehe...next time I'll pay more attention to formalities and efficiency...I swear! :)
Topic archived. No new replies allowed.