2

Today I encountered a problem with scanf functions. Assume that you have a structure like the following example.

struct structA{
  bool bVal;
  int nVal;
}

If you run the following code

structA a;

a.nVal = 7;
...// Assume that we read a text file and the only text is "0"
fscanf(fp,"%d",&a.bVal);

printf("\n a.bVal=%d",a.bVal);
printf("\n a.nVal=%d",a.nVal);

It will print

 a.bVal = 0
 a.nVal = 0

The reason is that the fscanf function assumes a.bVal is an integer and overwrites the a.nVal first 3 bytes. This problem can be solved by the following dirty solution.

structA a;

a.nVal = 7;
...// Assume that we read a text file and the only text is "0"
int nBVAL;
fscanf(fp,"%d",&nBVAL);
a.bVal = nBVAL;

printf("\n a.bVal=%d",a.bVal);
printf("\n a.nVal=%d",a.nVal);

My question is that is there a cleaner and straightforward way of avoiding this problem beside the solution explained?

UGU
  • 31
  • 3
  • Possible duplicate of [What is the printf format specifier for bool?](https://stackoverflow.com/questions/17307275/what-is-the-printf-format-specifier-for-bool) – Eugene Sh. Aug 11 '17 at 14:24
  • 3
    @EugeneSh. that post says bool is promoted when *reading*. OP's problem is with *writing* – meowgoesthedog Aug 11 '17 at 14:28

1 Answers1

8

The solution you're proposing is the only portable one.

There is no conversion specifier for _Bool. There's also no guarantee about the storage size of a _Bool, except that it has at least CHAR_BIT bits. Even if you knew the size and tried something like %hhd, entering anything other than 1 or 0 would create a value that's invalid for a _Bool (scanf() would access the object through a char pointer, possibly writing the padding bits of the _Bool).

The only safe thing to do is to take input of a type you can handle and convert this to a _Bool where needed, as you're doing in your example.

Note there's no similar problem with printf(). A _Bool passed to printf() is promoted to int, so %d is fine.