0

I have a file with a number of structs that contains a question, its answer and an identification number as well, each. So I created a function that returns the number of structs in the file, and another function that generates a random number between 1 and the number of structs. Individually these two functions work fine, but when I try to use the generated random number in the function below, the program stops in the first loop of the while... On the other hand, when I define a value to randNum, the function does what it should do: it checks the id of every struct and if the id equals the randNum defined value, the question is printed in the screen.

void generalKnowledge(){
    header();
    FILE* arquivo;
    question qst;
    int num=0;
    int temp;

    arquivo= fopen("generalKnowledge.txt", "rb");
    if(arquivo==NULL){
        printf("Falha ao abrir arquivo!\n");//"Failed to open file!"
    }
    else{

        int randNum;
        randNum= generateRandom(structCounter(arquivo));

        while(fread(&qst, sizeof(question), 1, arquivo)==1){
        
            if(randNum==qst.id){
                num++;
                printf(ANSI_COLOR_YELLOW "Questao %d: %s\n\n" ANSI_COLOR_RESET, num, qst.question);
                printf(ANSI_COLOR_MAGENTA "a) %s\n" ANSI_COLOR_RESET, qst.opta);
                printf(ANSI_COLOR_MAGENTA "b) %s\n" ANSI_COLOR_RESET, qst.optb);
                printf(ANSI_COLOR_MAGENTA "c) %s\n" ANSI_COLOR_RESET, qst.optc);
                printf(ANSI_COLOR_MAGENTA "d) %s\n" ANSI_COLOR_RESET, qst.optd);
                printf("\n\n");
            }
        }
    
    }
    fclose(arquivo);
}

//Below, the two first functions that I mentioned.


//This one counts the number of structs in the file
    int structCounter(FILE *arq){
        int count;
        int sz;

        fseek(arq, 0L, SEEK_END);
        sz = ftell(arq);

        count= sz/sizeof(question);

        return count;
    }

//This one generates a random number, using the return of the previous function as a limit
    int generateRandom(int count){
        int random;
        srand(time(NULL));
        random= 1+rand()%count;
        return random;
    }

Here's what happen when I run the code using the random number as a value in randNum

And here's the output when I define a value to randNum and run the code

  • 5
    Does this answer your question? [srand() — why call it only once?](https://stackoverflow.com/questions/7343833/srand-why-call-it-only-once) – Peter O. May 18 '21 at 23:26
  • 1
    If the identified duplicate candidate doesn't solve your problem then please update the post to describe the problem better than "doesn't work". Give complete code as a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) as well as the exact input, expected result and actual result. – kaylum May 18 '21 at 23:28
  • There is resevoir search. GIYF – wildplasser May 18 '21 at 23:39
  • @PeterO. I don't see how the proposed dupe can explain the error described – Support Ukraine May 19 '21 at 03:47

2 Answers2

1

I've just figured what was going wrong. I didn't add the command rewind() after seek() in the function structCounter(). Now it seems to work perfectly. Thank you all for the help!

0

You seem to be confusing question ID with the position in the file.

First you generate a random number to represent the position in the file, e.g. randNum equal 3 means the third question.

But when you read the file you compare the position to a question ID:

if(randNum==qst.id){
   ^^^^^^^  ^^^^^^
  position  question
  in file      ID

Maybe you want:

    while(fread(&qst, sizeof(question), 1, arquivo)==1){
        num++;             // Increcrement number of questions read, i.e. position
        if(randNum==num){  // Compare randNum to position
            printf(ANSI_COLOR_YELLOW "Questao %d: %s\n\n" ANSI_COLOR_RESET, num, qst.question);
            printf(ANSI_COLOR_MAGENTA "a) %s\n" ANSI_COLOR_RESET, qst.opta);
            printf(ANSI_COLOR_MAGENTA "b) %s\n" ANSI_COLOR_RESET, qst.optb);
            printf(ANSI_COLOR_MAGENTA "c) %s\n" ANSI_COLOR_RESET, qst.optc);
            printf(ANSI_COLOR_MAGENTA "d) %s\n" ANSI_COLOR_RESET, qst.optd);
            printf("\n\n");

            break; // end the loop
        }
    }
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63