Search code examples
cfor-looprandomsrand

Loop within a loop & random generation in c


I've been scratching my head for too long on this. I saw many topics on how to hadle random generation within a C loop, however I haven't seen anything when two loops are involved.

Here's my code below :

typedef struct
{
    char qh_uid[6];
    long int qh_vd;
    long int qh_pd;
    long int qh_id;
    double qh_value;
}quote_history;

int records_size = 20;
int batch_size = 5;

char *rand_str(char *dst, int size)
{
    static const char text[] = "abcdefghijklmnopqrstuvwxyz"
                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int i, len = size;
    for ( i = 0; i < len; ++i )
    {
        dst[i] = text[rand() % (sizeof text - 1)];
    }
    dst[i] = '\0';
    return dst;
 }

char *rand_tstp(char *dst, int size)
{
    static const char text[] = "0123456789";
    int i, len = size;
    for ( i = 0; i < len; ++i )
    {
        dst[i] = text[rand() % (sizeof text - 1)];
    }
    dst[i] = '\0';
    return dst;
}

double randfrom(double min, double max)
{
    double range = (max - min);
    double div = RAND_MAX / range;
    return min + (rand() / div);
}

quote_history *feed_batch(quote_history *qh_batch, int batchsize)
{
    int j;
    char mytext[6];
    char mylong[17];
    for (j = 0; j < batchsize; ++j)
    {
        quote_history qh_aux;
        printf("uid : %s - value : %lf\n",rand_str(mytext, sizeof mytext), randfrom(0,100000));
        strcpy(qh_aux.qh_uid, rand_str(mytext, sizeof mytext));
        qh_aux.qh_vd = strtol(rand_tstp(mylong, sizeof mylong), NULL, 10);
        qh_aux.qh_pd = strtol(rand_tstp(mylong, sizeof mylong), NULL, 10);
        qh_aux.qh_id = strtol(rand_tstp(mylong, sizeof mylong), NULL, 10);
        qh_aux.qh_value = randfrom(0,100000);
        qh_batch[j] = qh_aux;
    }
    printf("--------------\n");
    return qh_batch;
}

int
main(int           const argc,
     const char ** const argv) {

    quote_history *subArray;

    srand(time(NULL));
    int k;
    for (k = 0; k < (int)(records_size/batch_size); ++k) {
        subArray= (quote_history*)calloc(batch_size, sizeof(quote_history));
        subArray = feed_batch(subArray, batch_size);
        // Do something with subArray
        free(subArray);
    }
}

Well, basically, what I want to do is to generate batches (as an array) of struct quote_history where there is a random generation on some values, then treat the batch and move to another one.

For some reason, the random generation works well within the feed_batch function but when it moves to the next item in the loop, the batch remains the same ever and ever.

Forgot to paste the result of the code :

uid : qJfzrJ - value : 64938.995598
uid : LyCadK - value : 23030.096583
uid : dcOicU - value : 26016.211568
uid : BmpSTV - value : 76145.000279
uid : aQvABq - value : 92286.726130
--------------
uid : qJfzrJ - value : 64938.995598
uid : LyCadK - value : 23030.096583
uid : dcOicU - value : 26016.211568
uid : BmpSTV - value : 76145.000279
uid : aQvABq - value : 92286.726130
--------------
uid : qJfzrJ - value : 64938.995598
uid : LyCadK - value : 23030.096583
uid : dcOicU - value : 26016.211568
uid : BmpSTV - value : 76145.000279
uid : aQvABq - value : 92286.726130
--------------
uid : qJfzrJ - value : 64938.995598
uid : LyCadK - value : 23030.096583
uid : dcOicU - value : 26016.211568
uid : BmpSTV - value : 76145.000279
uid : aQvABq - value : 92286.726130
--------------

I've tried many combinations (loop within a loop instead of the feed_batch function for example) without success.

I hope someone will help me on that.

Florian


Solution

  • If I understand your code, what you are missing is the copying of the random generated string into your structure's array qh_uid. In fact you don't need to copy, you can generate the random string directly in your structure's buffer.

    quote_history *feed_batch(quote_history *qh_batch, int batchsize)
    {
        int j;
        for (j = 0; j < batchsize; ++j)
        {
            rand_str(qh_batch[j].qh_uid, sizeof(qh_batch[j].qh_uid) - 1);
            printf("uid : %s - value : %lf\n", qh_batch[j].qh_uid, randfrom(0,100000));
        }
        printf("--------------\n");
        return qh_batch;
    }
    

    Also what Sander De Dycker mentions in the comment is true, you can't write at qh_uid[6], the max you can write at is qh_uid[5], (by doing this, alignment considerations aside, you're in fact overwriting the first byte of qh_vd), remember array indices start at 0. Hence the -1 added to the size passed to rand_str.

    Also consider vlad_tepesch's answer about allocations.