Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Portability is a concern when using the fread() and fwrite() functions across multiple, heterogeneous systems. In particular, it is never guaranteed that reading or writing of scalar data types such as integers, let alone aggregate types such as arrays or structures, will preserve the representation or value of the data. Different compilers use different amounts of padding. Different machines use various floating-point models and may use a different number of bits per byte. In addition, there is always the issue of endianness.

Noncompliant Code Example

The following This noncompliant code example reads data from a file stream into a data structure.

Code Block
bgColor#FFCCCC
struct myData {
  char c;
  long l;
};

/* ... */

FILE *file;
struct myData data;

/* initialize file */

if (fread(&data, sizeof(struct myData), 1, file) < sizeof(struct myData)) {
  /* handleHandle error */
}

However, the code makes assumptions about the layout of myData, which may be represented differently on a different platform.

...

The best solution is to use either a text representation or a special library that will ensure the ensures data integrity of data.

Code Block
bgColor#ccccff
struct myData {
  char c;
  long l;
};

/* ... */

FILE *file;
struct myData data;
char buf[25];
char *end_ptr;

/* initialize file */

if (fgets(buf, 1, file) == NULL) {
  /* Handle Errorerror */
}

data.c = buf[0];

if (fgets(buf, sizeof(buf), file) == NULL) {
  /* Handle Error */
}

data.l = strtol(buf, &end_ptr, 10);

if ((ERANGE == errno)
 || (end_ptr == buf)
 || ('\n' != *end_ptr && '\0' != *end_ptr)) {
    /* Handle Error */
}

...