Search code examples
cscanfsatelliteuclinux

fscanf crashing while reading empty file


I'm working on a large project that has a function that reads a file of data. In certain test code however, That file doesn't exist, and so when it's created, it creates an empty text file. I wrote the following code to compensate for this event:

typedef struct system_boot_status_s{
  char timestamp[18];
  int power_down_type;
  int power_down_cause;
  int boot_number;
  int antenna_deployed;
  int images_captured;
  int beacon_count;
}system_boot_status_t;

////////////////////////////////

// Read the boot status info into the boot status struct
  ret = fscanf(f, "%s %d %d %d %d %d %d",
  bootstatus->timestamp,
  bootstatus->power_down_type,
  bootstatus->power_down_cause,
  bootstatus->boot_number,
  bootstatus->antenna_deployed,
  bootstatus->images_captured,
  bootstatus->beacon_count);

  if (ret != 7) // if 7 items weren't read
  {
    // Make sure all boot status members are set to 0
    snprintf(bootstatus->timestamp, BOOT_INFO_LEN, "xx-xx-xx-xx-xx-xx");
    bootstatus->power_down_type = 0;
    bootstatus->power_down_cause = 0;
    bootstatus->boot_number = 0;
    bootstatus->antenna_deployed = 0;
    bootstatus->images_captured = 0;
    bootstatus->beacon_count = 0;

    return -1;
  }

I know that fscanf returns the number of things it reads, but when I run this program and it reaches the empty file, my program just freezes. Am I missing something I should be doing with EOF? Can anyone help me out?


Solution

  • Arguments of fscanf (third and next) must be pointers to appropriate type. In the simplest case can use & operator

    Hard problem, no automatic casting from shorter int typed (char / byte)

    ret = fscanf(f, "%s %d %d %d %d %d %d",
      bootstatus->timestamp, // string
      &bootstatus->power_down_type, // int
    ...
      );
    

    This DEPENDS on declaration, only int declaration is allowed in my sample

    if there are not integers, use temporary variable. In this example timestamp is different kind of integral type (byte and so on)

       int tmp1;
    
        ret = fscanf(f, "%s %d %d %d %d %d %d",
          bootstatus->timestamp,
          &tmp1 ,
        ...
          );
    
        bootstatus->power_down_type = tmp1;
    

    Breaking of this rules give severe problems (depends on system, compilers etc)

    My answer is based on assumptions, not real declaration of this structure, unknown at moment of writing