Why below code wont generate a random string on multiple runs? [duplicate] - c

This question already has answers here:
Why do I always get the same sequence of random numbers with rand()?
(12 answers)
If I don't specify srand(), what seed does rand() use?
(5 answers)
Closed 5 years ago.
Program uses rand() function to generate random index. But it always produces same string no matter what! Why won't this work?
void rand_string()
{
int a[10];
int i;
char b[] = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM";
printf("%d", sizeof(b) / sizeof(b[0]));
for(i = 0; i < 10; i++)
{
int gen_rand = rand() % 63;
a[i] = b[gen_rand];
}
for(i = 0; i < 10; i++)
printf("%c", a[i]);
}

Use srand function to seed the random generator
srand((unsigned)time(NULL));
Note that you only have to seed once in your program otherwise it will not work properly.

You could firstly define a random function specific to your needs, i.e. generating in specific range (the length of the current string), like so:
int random(int min, int max)
{
return min + (rand()) / (RAND_MAX / (max - min));
}
then in your string-random-generator function you could also add a random length to every string:
void rand_str()
{
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"; // define only on first call
// call srand() using #include <time.h> ; could be outside of function, i.e. in main()
int length = random(0, 10); // get random length in [0, 10] on each call
// use length and random(0, sizeof(alphanum) / sizeof(alphanum[0])) in for loop
// everything else is the same...
}
use the keyword static to indicate single1 definition of the array alphanum (think of it that it is like making it global) and call function srand() once, before the use of random().
Note: you should consider modifying your function to a single purpose, i.e. only generating a random string and returning (a pointer to) a string; and printing it in a separate function.
1. Only on the first call of rand_str().

Related

random shuffle in c [duplicate]

This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 2 years ago.
I'm trying to shuffle an array by following order:
user inputs the size of array
user inputs number of times to shuffle
shuffling function should run by selecting two random number(index) and switching the value of indices. For example, if I made my array arr[10], the fuction should pick two random numbers in range 0~9 and switch positions.
If the user typed 2 in step2, the function should repeat picking two random indices 2 times.
I tried, but something seems wrong(the two numbers are repeatedly identical). How can I get real random numbers?
void shuffle(int arr[], int size) {
srand(time(NULL));
int temp, rand1, rand2;
rand1 = rand() % size;
rand2 = rand() % size;
temp = arr[rand1];
arr[rand1] = arr[rand2];
arr[rand2] = temp;
}
void total_shuffle(int arr[], int size, int num) {
for (int i = 0; i < num; i++)
shuffle(arr, size);
}
You're seeding the (P)RNG multiple times, most likely with the same value as time() returns seconds, ergo the sequence produced by rand() will be the same, unless your program takes multiple seconds to run, or spans across a one-second boundary. Only call srand() once in your application.

Difference in behaviour of rand() function in C [duplicate]

This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 5 years ago.
I am trying to implement multiply-shift algorithm for hashing and need to generate a new random number every time. I used a function to do the same as follows-
long mulShift(long x)
// returns h(x) for multiply shift function
{
srand (time (NULL));
long a = rand() % (long)pow(2,u);
if ((a>>1)<<1 == a)
a = a + 1;
long h = ((a*x) >> (u-k));
printf("%ld\t%ld\n", x, a);
return h%m;
}
Here u and k are global variables. If I call this function in a loop as follows-
for (int i = 0; i<5; i++)
mulShift(15);
I get the following output-
15 528638629
15 528638629
15 528638629
15 528638629
15 528638629
However, if I use srand before a for loop as follows-
srand(time(NULL));
for (int i = 0; i<10; i++)
{
printf("%d\n", rand()%1000000);
}
The output changes as follows-
638629
290058
512341
826358
80629
Why is this difference in behaviour? If I keep srand() inside the for loop in the last example, it again starts printing same values again and again. I apologise in advance if this is a stupid question.
Also, I'm using GCC on Ubuntu, if it makes a difference.
Here's the implementation of srand() and rand() in MSVC.
unsigned long rand_key;
void srand(unsigned long seed) {
rand_key = seed;
}
int rand(void) {
return ((rand_key = (rand_key * 214013L + 2531011L)) >> 16) & 0x7FFF;
}
Implementations on other platforms may differ, but they're essentially the same (calculating the next number from the current number). So calling srand() with the same seed is guaranteed to generate the exactly same sequence.
You can mix some stuff up to get a better seed:
#include <time.h>
#include <unistd.h>
srand( (unsigned)time(NULL) ^ getpid() );

How can i put different number in 2 array on C [duplicate]

This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 5 years ago.
I tried to put different random number element in each array.
However that 2 arrays got exactly same 10 random number.
What's wrong with me and how can I solve this?
#define MAX 100
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void number(int* array)
{
srand((long)time(NULL));
for (int i = 0; i < 20; i++)
array[i] = rand() % MAX + 1;
}
void printing(int* p_array)
{
for (int i = 0; i < 20; i++)
printf(" %d", p_array[i]);
puts("");
}
int main(void)
{
int score1[20];
int score2[20];
number(score1);
printing(score1);
number(score2);
printing(score2);
return 0;
}
srand((long)time(NULL));
When you are doing this, you are initializing srand with a seed based on the time the line has been called. The main point of a pseudo-number generator such as srand is that, whenever the seed is the same, the generator will always return the exact same serie of values, so a program using the generator with a specific seed can reproduce the exact same results several times.
The problem is that you initialize srand two times, and that the line is run two times at the exact same time (at least at the same second on such a short program), so the seed is the same. Your two arrays are, thus, strictly identical.
Call this line only once at the beginning of your main function, and you will use only one serie of numbers instead of two identical ones, leading to your two arrays having different values.
int main(void)
{
srand(time(NULL));
int score1[20];
int score2[20];
number(score1);
printing(score1);
number(score2);
printing(score2);
return 0;
}
Remove this statement from the number function
srand( (unsigned int)time(NULL));
and place it in main before the calls to number.
Otherwise the expression time(NULL) could yield the same value.
As 4386427 says, the problem is your call to srand(null). It resets the random number generator. If it didn't generate the same number series, then your number generator is broken. Remove it or call it with say the current time will fix the problem.

C array corrupted after calling a function

I have a simple C program which is supposed to fill an array with random values (this is the beginning of a school assignment). I'm using rand(), seeding it with srand(time()). Because this tended to generate somewhat predictable results when run repeatedly in a certain time period, I made another very simple function to give me a somewhat more random seed value:
time_t getRandomSeed(int numberOfIterations)
{
int i;
time_t result=time();
for (i = 0; i < numberOfIterations; i++)
{
result = randomizeSeed(result);
}
return result;
}
time_t randomizeSeed(time_t seed)
{
time_t result, fullTime, Modifier1, Modifier2;
srand((unsigned int)seed);
fullTime = time();
Modifier1 = time() >> (rand() % 10);
Modifier2 = (unsigned short)time();
Modifier2 <<= (rand() % 9 + 9);
result = fullTime ^ Modifier1 ^ Modifier2;
return result;
}
In main, I'm calling this inside srand() after declaring 2 int arrays. When I return to main, these arrays are garbage, and I can't figure out why.
int main(void)
{
int randomNumbers[ARRAY_LENGTH];
int sortedNumbers[ARRAY_LENGTH];
srand((unsigned int)getRandomSeed(2));
fillArray(randomNumbers, sizeof(randomNumbers) / sizeof(randomNumbers[0]));
return 0;
}
I set a breakpoint at line 4, and I have a perfectly normal unititialized array (at 0x00e1ea70 in the most recent run). Then I set another breakpoint at line 8, so I could see the array just before it was passed into fillArray. At this point, the address of the array is somehow 0xfffff04c, and all the elements show "unable to read memory", which I guess makes sense given the address is garbage.
Can anybody give me a clue what's happening to my array?
*Note, this is for a school assignment, so I don't really care if the RNG is secure, nor can I use any 3rd party libraries.
Update:
Per request, this is the body of fillArray(). However, from my question, the problem happens before we ever get to fillArray(), as I'm setting the breakpoint before it get's called.
void fillArray(int array[], size_t length)
{
size_t i;
for (i = 0; i < length; i++)
{
array[i] = rand()%1000 + 1;
}
return;
}
In your function randomizeSeed() you are calling time() three times in succession without an argument.
fullTime = time();
Modifier1 = time() >> (rand() % 10);
Modifier2 = (unsigned short)time();
The function prototype is
time_t time(time_t *timer);
So you should pay attention to your compiler warnings. From this point on, you have Undefined behaviour.

Using rand( ) to generate a random sequence of integers in C

I am trying to implement a function int choose_N(void) that generates and returns a random list of integers N (up to four integers). I am not sure if I am using rand( ) in the correct way, but this is what I have so far:
int choose_N(void)
{
int x, integer[4];
srand ((int) time(NULL));
for (x=0; x<4; x++)
integer[x]=rand();
return integer;
}
Would looping it like this work? Is time initialized in the correct way?
Two problems: most importantly, the array integer is local, and will go away when you return. If you want to return an array of things in C, you have to make the caller pass it in (see below). Secondly, srand() should only be called once per program, so it doesn't belong inside a function like this--it should be in main or some similar initialization function, otherwise multiple calls to this function will be correlated (at worst, they might even be identical). So here's a better approach:
void choose_n(int *out, int count) {
for (int i = 0; i < count; i += 1) {
out[i] = rand();
}
}
int main(int argc, char *argv[]) {
int results[4];
srand(time(NULL));
choose_n(results, 4);
}
Your loop is correct but your return statement will not work. The array integer is local to the function and will not be available outside. In either case, your function is supposed to return int and not an array.
And if you want to limit the random number to a range, you are better off using the mod operator such as rand() % range.
You could define your choose_N() like this
void choose_N(int integer[4])
{
int x;
srand ((int) time(NULL));
for (x=0; x<4; x++)
integer[x]=rand();
}
and use it likes this
int integer[4];
choose_N(integer);
You can't return a pointer to a local variable from a function.
See this post for the reason why? Can a local variable's memory be accessed outside its scope?
You have to allocate the array on heap.
Change it to:
int choose_N(void)
{
int x;
int *integer = (int*)malloc(sizeof(int)*4);
srand ((int) time(NULL));
for (x=0; x<4; x++)
integer[x]=rand();
return integer;
}
Don't forget to free() the memory when you are done.
In case you are wondering about malloc & free, you can read here:http://www.codingunit.com/c-tutorial-the-functions-malloc-and-free
About the random part:
If you really want to feel the randomness of c rand() seeded by time(0), you should run rand() like 3 times before you use it for generating actual numbers. To justify that, try running this code few times one after another while printing the numbers. You will notice that first one will be almost the same. My out:
1023384829 832292180 1773676349 957893636
1023401636 1114767429 1248842775 1942837294
1023418443 1397242678 724009201 780297305
So your srand should look like this:
srand ((int) time(NULL));
rand(); rand(); rand();

Resources