cc11

How to do file I/O with bool in C?


Should I treat a bool variable like an int when doing file I/O?
I mean is it correct to use the following code snippet?

bool b = true;
FILE *fp1, *fp2;
...
fprintf(fp1, "%d", b);
fscanf(fp2, "%d", &b);

I'd like to know the answer based on ISO C specifications.


Solution

  • Should I treat a bool variable like an int when doing file I/O?

    No, not for input.
    Yes, OK to use for output as the bool is converted to an int as part of being a ... argument and that int matches "%d".

    I mean is it correct to use ...

    Not certainly. It might work. It is undefined behavior (UB).

    I'd like to know the answer based on ISO C specifications.

    There is no C specified way to read a bool via fscanf() and friends.

    • bool lacks a scanf() input specifier.

    • The size of bool may differ from int. It might be the same as char or others.

    • If input like "0", "1" used and "true", "false" not needed, read in an int and convert.

    bool b = true;
    FILE *fp1, *fp2;
    ...
    fprintf(fp1, "%d", b);
    int tmp;
    fscanf(fp2, "%d", &tmp);
    b = tmp;
    
    • Alternatively, use a string.
    char tmp[2];
    fscanf(fp2, "%1[0-1]", tmp);
    b = tmp[0] == '1';
    
    • Additional work needed to accept "t", "FalsE", ...

    • Of course the return value of scanf() should be checked.

    • I'd consider a helper function:

    Rough idea.  (Not really that great, just for illustration.)
    
    // Read `bool` from `stdin`. Return 1 (success), EOF(end-of-file) and 0 in other cases.
    int scan_bool(bool *b) {
      char buf[2];
      int cnt = scanf("%1[01tfTF]", buf);
      if (cnt != 1) {
        return cnt;
      }
      *b = buf[0] == '1' || buf[0] == 't' || buf[0] == 'T';
      return 1;
    }