2010-09-30 87 views
0

。*精度不是在 指定的格式字符串,但作爲一個 附加整數值參數 ,其具有是 格式化參數之前。我可以在兩個字符串的字符串格式中使用兩個精度'*'嗎?

#define SUFF ".txt" 
#define MAX_STR 50 

fileName[MAX_STR]; 
name ="myFile" 

sprintf(fileName, "%s%s", name, SUFF); //fileName = "myFile.txt" 

現在我想結合精確的字符串。

我試圖做的基本的東西(但更多的動態計算,這就是爲什麼我使用「*」)是:

sprintf(fileName, "%.*s%.*s", 46, 4, name, SUFF); 

然而,即使是這樣創建一個運行時異常。

更具體地說:

sprintf(fileName, "%.*s%.*s", 
     MAX_STR - (int) sizeof(SUFF), (int) sizeof(SUFF), 
     name, SUFF); 
+0

請 - 如果它是可用的你使用'snprintf'來代替。 – dreamlax 2010-09-30 23:16:39

+0

唯一的問題是用snprintf如果名稱碰巧很長,我們可能會丟失.txt。使用精度保證.txt將成爲字符串的一部分。 – 2010-09-30 23:39:34

回答

3

你的可變參數錯誤的順序。寬度參數與對象參數一起使用(它必須立即在對象之前)。

sprintf(fileName, 
     "%.*s%.*s", 
     MAX_STR - (int) sizeof(SUFF), // precision and... 
     name,       // ...object 
     (int) sizeof(SUFF),   // precision and... 
     SUFF       // ...object 
     ); 

即使你打算使用寬度指定,但仍遠不如用snprintf而不是sprintf

+0

啊,我看它是如何工作的,謝謝... – 2010-09-30 23:13:55

2

您在最後的sprintf中混淆了參數的順序。它應該是這樣的:

sprintf(fileName, "%.*s%.*s", 
     MAX_STR - (int) sizeof(SUFF), name, 
     (int) sizeof(SUFF), SUFF); 

有注意到這裏值得一些額外的東西:

  1. sprintf是錯誤的工作工具,如果你分配在編譯時定義字符串,並通過精密這是不必要的,因爲尺寸也是固定的。像char fileName[] = "myFile" SUFF;就足夠了。
  2. 一個好的編譯器(我猜你正在使用MSVC的古老風格),實際上會解析出參數sprintf,並在編譯時告訴你有關你的錯誤。看看format attribute
1

一個更容易的選擇是asprintf() - 如果它足夠便攜(當我使用C而不是C++時,最後一次使用時會出現問題) - 希望它現在是標準化和通用的。它不像mallocs內存那麼快,你需要明確釋放後,但它可以讓程序員在格式化方面思考任何輸入是什麼,而不必跳過箍環或在其大小上添加任意限制,這可以避免許多小錯誤和限制。

相關問題