Okay, thanks ahead of time for looking at this.

First off the program is in C, not C++.

I am trying to read in from a text file... a certain question.... but i fairly suck at programming in C. I have a file pointer set up and i have it run the file open system... I want it to randomly select a question from the file and display that question.

here is the main questions..
which is more efficient?

A) doing:

fr = fopen("questions.txt", "rt");

and then creating an array to store this WHOLE file in?
ie.

char questions[400][400];

and then read them all in with nested for loops?

B) reading from a certain part of the file... like the certain line...
I am sure this is more efficient but i dont really know how to do this?

i know you can do something like this:

while (fgets(s,1000,f)!=NULL)
        printf("%s",s);

but im just confused how you would implement the random number phase into that string... or if it is possible..


I will post the generic parts of my code... (can post my whole thing if requested... but its mainly a hardware program for a certain processor and might not be relevent)

FILE *fr;

void displayQuestion() {

/* fr is a FILE pointer.  This pointer will read text from 
   the "questions.txt" file */
fr = fopen("questions.txt", "rt");



fclose(fr);

}

void main(void)
  {

  /* Initialize the SCI */
  SCIBDL = 52;
  SCICR2 = 0b00101100;
    
  /* Enable Interupts */
  EnableInterrupts;
  
  srand((unsigned)time(NULL));

  Login(); 
  /* Loop Forever */  
  for(;;) 
    {
   
     
    } 
  }

Now... before people say things like... why do you do void main(void)... its the way the processor program is set up... and the looping forever at the end.... both are needed (and these are new processors.... from freescale corp.)

i am basically asking for consulting advice on this system.... thank you.

there are at least a couple ways you can approach the problem.
1. Read the whole file into an array as you posted. Then generate a random number between 0 and the number of lines read -- see rand() function. That can take a lot of memory if the file is really huge. If you have learned about pointers, then you would want an array of pointers, so that the memory for the lines can be allocated to the exact length of the lines

2. Don't read all of it into memory -- leave it on the hard drive. When the program starts, loop though the file using fgets() and count the number of lines in the file. Generate a random number as #1 above, rewind the file, and re-read using fgets() until the line number has been read. Example: the file contains 50 lines, generate a random number between 0 and 50, lets say 5, then read the first five lines.

i appreciate the reply.

Yes, i was gonna use the rand() function like you suggested. But for the fgets.... Reading the whole file first using them, then re-reading the file? I dont understand that. What does the first reading do exactly if you are going to reread it?

As for the memory, the file would be about 50 lines. And at the end, if you do a rand() and it is 5... it would read the first 5 lines using an fget() (i get that) but would it output all 5 with an fget()? because I would only want that fifth line.

NOTE:
I learned C++ and can handle the pointers and everything, but these new functions im not used to in C are kind of a pain!

Thanks :)

i appreciate the reply.

Yes, i was gonna use the rand() function like you suggested. But for the fgets.... Reading the whole file first using them, then re-reading the file? I dont understand that. What does the first reading do exactly if you are going to reread it?

The first reading is to count the number of lines in the file so that you can limit the range of numbers returned by rand(). The second reading is to access a specific line number. Two readings are necessary when the file is too large to fit in memory all at one time.

As for the memory, the file would be about 50 lines. And at the end, if you do a rand() and it is 5... it would read the first 5 lines using an fget() (i get that) but would it output all 5 with an fget()? because I would only want that fifth line.

With a file that small, just read the whole thing into an array -- again you need all for the same reason as above -- so you can limit the return value of rand(). If the file has 50 lines you don't want rand() to give you a number of 1,000!

NOTE:
I learned C++ and can handle the pointers and everything, but these new functions im not used to in C are kind of a pain!

All those functions are standard C. There is nothing that is not part of ansi C standards. And they are all available in c++ too. I don't know of a c++ replacement for rand(), although there could be. I don't know much about boost libraries -- but that's pretty advanced c++ stuff anyway.

All those functions are standard C. There is nothing that is not part of ansi C standards. And they are all available in c++ too. I don't know of a c++ replacement for rand(), although there could be. I don't know much about boost libraries -- but that's pretty advanced c++ stuff anyway.

Yeah i know how to use rand() and the only thing about reading it in to figure out the size.... if i know its 50 lines... can't i just set that part of the array to 50 and for rand() just do the rand(( % 50) + 1) type thing?

i was referring to the fgets() i never used them in the c++...

thanks dragon!

Yeah i know how to use rand() and the only thing about reading it in to figure out the size.... if i know its 50 lines... can't i just set that part of the array to 50 and for rand() just do the rand(( % 50) + 1) type thing?

Yes you could do that, but then what happens when you choose a different file with a different number of lines? In that case you have to recompile your program.

i was referring to the fgets() i never used them in the c++...

Oh, now I understand. C file i/o is a little different. Here is an example, just in case you are confused.

#include <stdio.h>

int main()
{
   // buffer for file i/o
   char buf[255]; // just an arbitrary size here.  I'd rather it be too big than too small.
   // open the file for reading
   FILE* fp = fopen("somefile.txt","r");
   if( fp == NULL)
   {
      printf("Can't open the file\n");
      return 1;
   }
   // read each line of the file
   while( fgets(buf,sizeof(buf),1,fp) != NULL)
   {
      // count the lines or do other stuff here
   }
   // close the file
   fclose(fp);
   return 0;
}

Soln:
we can solve this problem by storing all the offset values into an array.
Do the following steps
1. Read all the questions from the file and strore all offsets into an offset array.(For the first time only)
2. Generate any random number (act as index) which is less then the array size
3. Goto the offset array with the generated index value(random number)
4. Collect the offset from array and store it in a temperary value.
5. Open the file
6. use fseek function and pass the collected offset value.
7.It moves the file pointer to the particular question
8.Use fgets to read a whole line ie. whole question
9.Display the question wherever u want.

Advandages:
1. No need of reading entire file
2. No need of storing all questions to an array
3. Gives quick access to any question, any where in the file.
4. It takes less memory

Offset - Byte location in file

If you have any queries pla feel free to mail to << snipped email id>>

Regards,
Jeganathan Krishnasamy.

This article has been dead for over six months. Start a new discussion instead.