2012-05-05 58 views
0

我在最後一行得到一個「int格式,不同類型arg(arg 4)」錯誤。我應該只投射到int還是有更好的方法來處理這個?Cast off_t到int

struct stat info; 
if (stat(file_path, &info) == -1 || errno == ENOENT) 
    return -1; 

if (stat(file_path, &info) != -1) 
{ 
    char buf[LINELEN]; 
    snprintf(buf,LINELEN,"File Size: %d",info.st_size); 
+3

關於'printf'(這讓我真的很難過)的壞處恰恰就是格式字符串的問題。想象你的代碼根據某種配置typedefs爲'uint32_t'或'uint64_t'的類型。你永遠不能只是printf這些變量。但是,絕大多數工作沒有問題的解決方案是將參數轉換爲它們可以承擔的最大大小。以你的情況爲例:'printf(「%lu」,(unsigned int)info.st_size);'無論大小如何,都能正確打印。唯一的問題是,如果論點比你的演員大。你會失去數據,但仍然避免UB。 – Shahbaz

回答

0

改爲嘗試格式%ld。這取決於你的平臺,但通常off_t被定義爲long。也可以是無符號的,在這種情況下使用%lu。

0

對於off_t類型,你應該打印這樣的:

snprintf(buf,LINELEN,"File Size: %jd",info.st_size); 

注意的j在格式化。

+0

「j」格式適用於「{u} intmax_t」。所以你也必須投入這種類型以確保。 –

0

st_size的類型是off_t,這實際上是long

所以正確的電話應爲:

snprintf(buf,LINELEN,"File Size: %ld",info.st_size); 
+0

「真的很長」?它可以是任何有符號的整數類型。 –

+0

所以,你認爲「j」修飾符會出現在所有的實現中嗎?假設它是長期的更安全。您可以在不帶任何編譯器警告的情況下強制轉換st_size:'snprintf(buf,LINELEN,「文件大小:%ld」,(long)info.st_size);' – 2012-05-05 10:03:19

+0

「j」修飾符是C標準的一部分。 AFAIR自C99以來就是如此。 –

3

不幸的是沒有爲off_t定義的格式可以是任何符號的整數類型,根據不同的平臺,也對一些宏(調節,如果你可以訪問例如大於4 GiB的文件)。你不能依賴這個。最好使用「j」作爲printf格式的長度修飾符,並將您的值轉換爲intmax_t

0

爲了安全,正確和可移植:在傳遞可變參數時總是包含顯式轉換,例如,如果您要傳遞的內容在編譯時可能不具有相同的類型,則傳遞給printf。例如,計算出你認爲off_t可以得到多大(long應該至少和off_t一樣大),然後確保你的printf格式能夠接受你現在可以安全地知道你會傳入的那一長串。對於可能變化的類型,沒有轉換的printf會要求麻煩。