2017-08-11 113 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沒問題。