Pergunta

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

Foi útil?

Solução

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.

Outras dicas

your main allocates one field of quote_history and frees it in the for loop.

the feed_batch takes this pointer and accessed it as if it would be an array --> your debugger should report memory access errors.

new guess:
i have an idea why you my think that it does work (the printfs are correct) but outside it does not work. But it is a guess only since code is missing: I guess you save the mytext pointer in your structure. so at the end all your array elements pointing to the same string. And even worse that string is an automatic variable that looses scope after exiting feed_batch.

Btw:
why do you need dynamic allocation? simply declare an object of quote_history and pass its pointer. or declare an array of quote_history objects. dynamic allocation is not neccessary here.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top