简体   繁体   中英

Read file line by line from file “dynamically” in C using method

I have a file that i want to read line by line, but it has to be done dynamically, meaning that it should only read a line when i call the method. And once i call the method next time, it should read the next line of the file, and so on. So far i have only been successful in reading all lines in the file, or the same line over and over again.

Here are my code pieces:

file with method:

int getNextData(){
static const char filename[] = "file.txt";
   FILE *file = fopen ( filename, "r" );
   if ( file != NULL )
   {
      char line [ 5 ]; /* or other suitable maximum line size */

      if ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
      {
         fputs ( line, stdout ); /* write the line */
      }
   }
   else
   {
      perror ( filename ); /* why didn't the file open? */
   }
   return 0;
}

main file:

int main () {
     // this should give me two different numbers
getNextData();
    getNextData();
return 0;
}

I have left out the "include", but that part is right.

Output in this case is the same line twice.

Can anyone please help me?

The problem is most likely that you're opening the file each time, thus resetting the file pointer. Try opening it just once in your main function and passing the file handle to the function to do the reading.

Here's some modified code that should work for you:

#include <stdio.h>

int getNextData(FILE * file){

   if ( file != NULL )
   {
       char line [ 5 ]; /* or other suitable maximum line size */

       if ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */       
       {          
          fputs ( line, stdout ); /* write the line */       
       }    
   }    

  return 0; 
}

int main () {      // this should give me two different numbers 
  static const char filename[] = "file.txt";
  FILE *file = fopen ( filename, "r" );
  getNextData(file);     
  getNextData(file); 
  return 0; 
} 

With this code, given the file:

mike@linux-4puc:~> ls -l file.txt
-rw-r--r-- 1 mike users 15 Sep 11 18:18 file.txt
mike@linux-4puc:~> cat file.txt
bye
sh
ccef

I'm seeing:

mike@linux-4puc:~> ./a.out 
bye
sh

You need to somehow maintain state, in this case where in the file you are located, between calls.

The easiest way would be to make the FILE * live on:

int getNextData(void) {
  static const char filename[] = "file.txt";
  static FILE *file = NULL;

  if( file == NULL )
    file = fopen ( filename, "r" );

  /* rest of function */
}

Note that this is a bit ugly, it makes it impossible (since the function is void ) to eg re-start the reading, and what happens when the file ends? But it's the easiest way. You should be able to build on this.

Just a side-note: your task is I/O-related, yet from your description it looks like it does nothing to the data you read from file (apart from echoing it back). This perhaps muddies up the suitable solution.

I'd try to look beyond language syntax and focus on the intended program functionality. In one approach you may define a program state structure/handle to contain file pointer, line number,buffer etc. Your function then would take the state from the handle and read the next line from file into .

So the flow may be: init(appstate, filename) ==> loop:{ read_file(appstate) ==> process_line(appstate) } ==> end(appstate)

This makes program-flow clearer and avoids using static variables by explicitly defining the program state.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM