0

I'm trying to write a program that will select a random word from my array for hangman, I have the following code. Without int n = rand() % 10; words = word1[n]; the code list all the words in the dictionary, with the code it crashses, is there another way to achieve this? I want the code to select a single word, MAX_WORDS = 106184.

james
  • 1
  • 7

3 Answers3

4

If i get your code right, you come out of the loop while (wordIndex < MAX_WORDS) when wordIndex == MAX_WORDS

and you return myWords[wordIndex]; which is off the subscript limit by 1.

theAlias
  • 396
  • 1
  • 14
  • Yes that correct, `MAX_WORDS` is how many words there is in the dictionary. – james Oct 01 '13 at 15:14
  • @james: how can this be "correct"? Do you realize this *is* the source of your exception? You *probably* want to return a random word out of the entire list (never mind the confusing function name), so do `return myWords[rand() % MAX_WORDS]->GetWord();` – Jongware Oct 01 '13 at 15:38
  • @james Why did you remove code from ur question? And, You do realize that `myWords[MAX_WORDS]` would be out of allowable array index, right? – theAlias Oct 01 '13 at 16:17
1

If RAND_MAX > MAX_WORDS then you can just do:

Word* Dictionary::ListWord() 
{
    int n = rand() % MAX_WORDS;
    return myWords[n];
}

A couple gotchas here, note that the distribution of rand() % MAX_WORDS isn't exactly uniform due to the modulo operator (lower values are slightly more likely), but it usually is close enough to uniform as long as the modulo is small relative to MAX_RAND.

Second more important gotcha is that rand() will only generate numbers less than RAND_MAX, and on some platform RAND_MAX, and RAND_MAX is only guaranteed to be greater than 2^16 which is less than 106184. To avoid this issue, if you have a relatively modern C++ compiler, you can use the <random> module from TR1, i.e. http://en.cppreference.com/w/cpp/numeric/random. On older compiler you can also use boost's random module.

Otherwise, if you're stuck with an old compiler and you can't use neither TR1 random library or boost random library, this is a simple ways to generate large random numbers:

// taken from: http://stackoverflow.com/a/7920941/309412
// this generates a random 64-bit integer
uint64_t rand64() {
    return (((uint64_t) rand() <<  0) & 0x000000000000FFFFull) | 
           (((uint64_t) rand() << 16) & 0x00000000FFFF0000ull) | 
           (((uint64_t) rand() << 32) & 0x0000FFFF00000000ull) |
           (((uint64_t) rand() << 48) & 0xFFFF000000000000ull);
}
Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
1

word1 is a single word. word1[n] is the n+1'th letter (C++ starts counting at 0, word1[0] is the first letter). Since n is random, you have to ensure that every word has at least 10 letters. Is that the case? Picking the tenth letter of "cat" is likely to crash.

Also, you never pick the 11th letter of word1. That's probably not intentional. In fact, are you even trying to pick random letters?

MSalters
  • 173,980
  • 10
  • 155
  • 350