2009-02-13 71 views
11
sscanf(input_str, "%5s", buf); //reads at max 5 characters from input_str to buf 

但我需要使用類似%MACRO_SIZEs代替%5S如何在sscanf中傳遞可變長度寬度說明符?

一個平凡的解決方案是創建一個格式字符串爲同一

char fmt_str[100] = "";  
snprintf(fmt_str, 100, "%%%ds", MACRO_SIZE); 
sscanf(input_str, fmt_str, buf); 

有沒有更好的方法來達到同樣的?

回答

8

如果您MACRO_SIZE是常量在編譯時,你可以試試這個:

#define MACRO_SIZE "5" 
snprintf(fmt_str, 100, "%" MACRO_SIZE "s", buf); 
+0

約束不是那麼多,MACRO_SIZE評估爲一個常量,但它的定義是一個簡單的文字,對嗎?例如,定義(5 * 25 + 3)(在編譯時計算常量)會導致`snprintf(fmt_str,100,「%」(5 * 25 + 3)「s」,buf) – jhfrontz 2015-11-04 17:44:17

9

像斯特凡說,但對於sscanf()更恰當地回答這個問題,並與多一點宏權謀:

#define MACRO_SIZE 5 

#define FORMAT(S) "%" #S "s" 
#define RESOLVE(S) FORMAT(S) 

char buf[MACRO_SIZE + 1]; 
sscanf(input_str, RESOLVE(MACRO_SIZE), buf); 

這使用C的相鄰字符串文字自動連接在一起,以在編譯時形成所需的格式字符串。這隻適用於MACRO_SIZE是預處理宏,如果它是一個正常的運行時變量。

需要通過RESOLVE()額外的宏調用,因爲否則的說法不會被解析爲其#define d值,我們想最終的"%MACRO_SIZEs"一個格式化字符串,這不是我們想要的。

+0

如果`MACRO_SIZE`是一個表達式(例如`(4 + 1)`或引用另一個宏(例如`#define MACRO_SIZE(OTHER_MACRO-1)`),那麼您是否期望這可以工作?當我嘗試它時,使用`gcc -E`來查看預處理器後的輸出,它沒有擴展到最終值 – meowsqueak 2016-10-03 21:06:28

1

「正確」的解決方案就是你所說的微不足道的解決方案。所有這些聰明的宏(我會自己使用m4)只會讓你的代碼更易於管理,那麼如果你只是把它作爲一個常量離開它。

您在這裏遇到的問題是字符串不是C中的第一類數據結構。它們是字節數組。因此,您必須構建您想要的數組以獲得所需的含義,然後使用sprintf構建該數組。這並不漂亮,但它是正確的。

如果您遇到性能問題,並且您已將它跟蹤到此處,那麼請清除函數調用。但是除非MACRO_SIZE的值重複了一百次,或者分散在多個文件中,否則我只是改變文字。宏只是假裝有更多的靈活性,使用sprintf實際上給你靈活性。

相關問題