fscanf crashing while reading empty file

1k Views Asked by At

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?

2

There are 2 best solutions below

9
Jacek Cz On BEST ANSWER

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

0
kocica On

You are passing an int (by value) to function which accepts pointers to variables (int*).

Just simply pass an address of variables and it shouldnt freeze anymore. You can get variables address by deregerencing it &var.

  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);

to

  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);

But not to the strings! Despite the fact that &timestamp points to same address as timestamp.