2017-08-11 193 views
2

今天我遇到了scanf函数的一个问题。假设你有如下例子的结构。使用fscanf读取布尔值

struct structA{ 
    bool bVal; 
    int nVal; 
} 

如果您运行下面的代码

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

它将打印

a.bVal = 0 
a.nVal = 0 

的原因是fscanf函数假定a.bVal是一个整数,并覆盖a.nVal前3个字节。这个问题可以通过以下肮脏的解决方案来解决。

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

我的问题是,有没有一种更清洁,直接的方法来避免解决方案旁边的解决方案?

+0

可能的重复[什么是bool的printf格式说明符?](https://stackoverflow.com/questions/17307275/what-is-the-printf-format-specifier-for-bool) –

+2

@EugeneSh。那个帖子说bool在*阅读*时被提升。 OP的问题是*写* – meowgoesthedog

回答

7

您提出的解决方案是唯一的便携式解决方案。

_Bool没有转换说明符。除了它至少有CHAR_BIT位之外,也不保证_Bool的存储大小。即使你知道大小,并试图像%hhd,进入以外的任何其他10将创建一个值,该值是无效的_Boolscanf()将通过char指针访问对象,可能写填充比特的_Bool)。

要做的唯一安全的事情就是接受您可以处理的类型的输入,并在需要时将其转换为_Bool,就像您在示例中所做的那样。

请注意,printf()没有类似的问题。 A _Bool传递到printf()被提升为int,所以%d没问题。