Skip to content

File I/O

The FILE * Data type

  • In C, the FILE * type is commonly used to represent a stream.
  • Streams are largely categorized 2 ways: text and binary.
  • The file pointer is automatically updated by the standard library to point to the next character in the file after each read operation.

Reading text files

  • Text files are logically a sequence of lines separated by newlines.
    • Read char by char
      #include <stdio.h>
      int main(void){
      FILE *fp;
      int c; //EOF is the reason we need to use integer, but deep down it's a char
      fp = fopen("../hello.txt", "r");
      while ((c = fgetc(fp)) != EOF ){
      printf("%c",c);
      };
      fclose(fp);
      }
    • Read line by line
      #include <stdio.h>
      int main(void){
      FILE *fp;
      char s[1024]; // Big enough for any line this program will encounter
      int linecount = 0;
      fp = fopen("../hello.txt", "r");
      while (fgets(s, sizeof s, fp) != NULL){
      printf("%d: %s", ++linecount, s);
      }
      fclose(fp);
      }
    • Read and store values on variables
      #include <stdio.h>
      int main(void){
      FILE *fp;
      char name[1024];
      float length;
      int mass;
      fp = fopen("whales.txt","r");
      while (fscanf(fp, "%s %f %d", name, &length, &mass) != EOF){
      printf("%s whale, %d tonnes, %.1f meters\n", name, mass, length);
      }
      fclose(fp);
      }

Writing Text files

#include <stdio.h>
int main(void){
FILE *fp;
int x = 32;
fp = fopen("output.txt", "w");
fputc('B', fp);
fputc('\n', fp);
fprintf(fp, "x = %d\n", x);
fputs("Hello World!\n", fp);
}

Writing bytes to files:

  • With binary files, we only get a raw stream of bytes, that’s all.
  • Because it’s a stream of bytes, it can contain NUL characters.
  • Use fread and fwrite instead.
#include <stdio.h>
int main(void){
FILE *fp;
unsigned char bytes[6] = {5,37,0,88,255,12};
fp = fopen("output.bin", "wb"); // wb mode for "write binary"!
// Data to write, size of each "piece" data, counter of each "piece" of data, FILE *
fwrite(bytes, sizeof(char), 6, fp);
}

Reading bytes to files

#include <stdio.h>
int main(void){
FILE *fp;
unsigned char c;
fp = fopen("output.bin", "rb"); //rb for "read binary"!
while (fread(&c, sizeof(char), 1, fp) > 0){
printf("%d\n", c);
}
}

Struct and Number Caveats

=> Solution: serialization (like Protocol Buffer)