2

I am reading a growing input file, and do some work and write the info to the output file. I have some conditions to work on the growing file. But I am failing at exiting from the loop.

FILE *logfile;

int main(int argc, char *argv[])
{
  char *filename;
  char *logfilename;
  FILE *infile;
  char line_buf[255];
  char *line;

  sleep(3);

  if (argc < 3) {
    fprintf(stderr, "Usage: %s <filename> <logfile>\n",
            argv[0]);
    return -1;
  }
  filename = argv[1];
  logfilename = argv[2];


  infile = fopen(filename, "rb");
  if (infile == NULL) {
    fprintf(stderr, "Failed to open file\n");
    return -1;
  }

  logfile = fopen(logfilename, "w");
  if (logfile == NULL) {
    fprintf(stderr, "Failed to open logfile - are permissions correct?\n");
    return -1;
  }

  while(1){
    line = fgets(line_buf, sizeof(line_buf), infile);


    if (line == NULL){
      if(feof(infile))
           clearerr(infile);
      failedReads++;
      usleep(25000); //wait for the data from live file
      continue;     
    }

    else{  
            if(feof(infile))
                   break;
    }

    ...........
    //do some work
    ...........
  }

 fclose(infile);
 fclose(logfile);
}

My output log file is getting the data only after the input file stops growing(means at the end of execution). I want my output logfile to get the data by time(means output file is not growing). I have a python script for create a growing file(If anyone really wants to work my issue).

#/usr/bin/python
import time
with open("input.txt") as f:
    fileoutput = f.readlines()
with open("out.txt", "a+") as f1:
    for line in fileoutput:
        f1.write(line)
        f1.flush()
        time.sleep(0.01)
geo-freak
  • 327
  • 3
  • 20
  • You wrote `if (line == NULL)` then `else { if (line == NULL) ...` which seem contradictory to me. – Federico klez Culloca Jul 30 '19 at 12:32
  • 1
    your code wont even enter the `else if (line==NULL)` which would leave the loop – olivecoder Jul 30 '19 at 12:33
  • I haven’t read your question completely, but giving a quick read, the problem seems that you want real-time logging? Like immedieately when you get input, you want your output. Usng `FILE *` kind of file handling, data is not written in real time because its buffered and written in one go. If you want data to be written as soon as inputted, either fflush it or using `read(2)` and `write(2)` after getting a fd from `open(2)`. – Mihir Luthra Jul 30 '19 at 12:35
  • Generally: Please don't write code like `if(condition) { } else if(!condition) { }` (which is what you actually intended), that's just redundant and serves for nothing, just write `if(condition) { } else { }` (of course, *do* write `if() {} else if() { }` if conditions are *not* complementary...). – Aconcagua Jul 30 '19 at 12:37
  • @FedericoklezCulloca I just modified my code, even though not getting the expected result. – geo-freak Jul 30 '19 at 13:02

1 Answers1

1

Code is waiting indefinitely for additional data. Code just waits longer and longer with usleep(25000*failedReads).

// Ineffective code
if (line == NULL){
  if(feof(infile))
       clearerr(infile);
  failedReads++;
  usleep(25000*failedReads); //wait for the data from live file
  continue;     
}

else{
        if(line == NULL)  // this can never be true!
                if(feof(infile))
                        break;
}

"to get the data by time(means output file is not growing" implies there should be an upper bound of time that if the input file fails to provide more data, quit the loop.

Look for 2 successive read failures. If waiting after the first failure does not provide more data, time to leave.

// instead
bool failed_read_flag = false;
while(1){
  line = fgets(line_buf, sizeof(line_buf), infile);
  if (line == NULL){
    if (failed_read_flag) {
      break; // 2 successive read fails 
    }
    if(!feof(infile)) {
      break; // Rare input error just occurred.
    }
    clearerr(infile);
    failed_read_flag = true;
    usleep(25000 /* us */); //wait for the data from live file
    continue;     
  }
  failed_read_flag = false;

  // Do some work
}

Strange to open a file with infile = fopen(filename, "rb"); and then use it with fgets().

It the file is a text file, use fopen(filename, "r"). If the file is binary, use fread().

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256