-1

So I am working on this for loop(s) here:

    for (int i = 0; i < num; i++) {
        for (int i = 0; i < length; i++) {
            Str += randGen();
        }
        cout << Str << endl;
    }
}

And for context, the integer 'length' is a randomly generated string size. Here is my randGen() function:

static const char combination[] =
"0123456789"
"!@#$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";

int stringLength = sizeof(combination) - 1;

char randGen() {

    return combination[rand() % stringLength];
}

Basically my issue is that if 'num' is greater than one, it will print out the beginning randomly generated part for each one of them the same, and it will not change. The only time there are new randomly generated characters is when the size of 'length' increases, and that is it. However, I want all the STRs to be completely different. Can anyone help me?

--Thx in advance--

Bassie-c
  • 198
  • 16
Marc M.
  • 39
  • 3
  • You keep appending to the same string. Every time you print it, it repeats the previous prefix plus the newly added characters. Maybe that is what tricks you into thinking the same characters are generated. You'd probably want to clear `Str` in between loops. – Igor Tandetnik Jan 12 '19 at 04:30
  • @Igor Tandetnik Yeah, that's what i thought. Thanks, this really helped. – Marc M. Jan 12 '19 at 04:43
  • 1
    Try adding `srand(time(NULL));` before you call `rand`. It will set the seed for `rand` based on the current time. This should only be called once (at the beginning of your program, for example). – McAngus Jan 12 '19 at 04:43
  • 1
    In C++, you should be using `std::string` and C++ random generators in the `` headers because they're easier to use. For example, you won't forget to set the seed at the beginning of your program because a seed is required in order to construct the random generator. – eesiraed Jan 12 '19 at 05:14
  • 1
    It's a really bad idea to use the same variable name for your loop control variable on both your inner and outer loops. While it does compile, it will lead to a world of pain when you have to debug a problem. – user1118321 Jan 12 '19 at 05:46

1 Answers1

1

If you want to get runtime-dependent outputs with rand(), you should make it's seed depending on runtime environment. As suggested in comment, a simple way is calling srand(time(NULL)) once before num-loop:

DEMO.

srand(time(NULL));

for (int i = 0; i < num; ++i)
{
    for (int j = 0; j < length; ++j) {
        Str += randGen();
    }
    
    std::cout << Str << std::endl;
}

Although rand() should be usually implemented as the Park-Miller LCG, but, for instance as noted in C++ standard draft n4687, the algorithm used in rand() is completely compiler implementation defined:

29.6.9 Low-quality random number generation [c.math.rand]

int rand();
void srand(unsigned int seed);

... rand’s underlying algorithm is unspecified. Use of rand therefore continues to be non-portable, with unpredictable and oft-questionable quality and performance.

Fortunately, in C++11 and over, we can use <random> to generate a guaranteed quality randomness. Thus I recommend you to use them as follows. If you need more high-quality randomness, you can use std::mt19937 instead of std::minstd_rand:

DEMO

#include <random>

static constexpr char combination[] =
"0123456789"
"!@#$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";

constexpr int stringLength = sizeof(combination) - 1;
std::minstd_rand gen(std::random_device{}());
std::uniform_int_distribution<std::size_t> dis(0, stringLength-1);

char randGen() {
    return combination[dis(gen)];
}
Community
  • 1
  • 1
Hiroki
  • 2,780
  • 3
  • 12
  • 26