2011-09-28 63 views
1

我想創建一個全球性的22字符(+ NULL)字符串中的C.我初始化這樣的:如何用16位整數初始化C字符串?

#define SVN_REVISION  "1143" 
#define SERIAL_NUMBER "PST3201109270001" 
char general_info[23] = SVN_REVISION SERIAL_NUMBER SAMPLING_FREQUENCY; 

到目前爲止,這工作正常。 general_info使用兩個字符串的連接進行初始化。現在,對於最後兩個字符,我希望它們是一個16位整數。但我不能簡單地這樣做:

#define SVN_REVISION   "1143" 
#define SERIAL_NUMBER   "PST3201109270001" 
#define SAMPLING_FREQUENCY (UINT16)500 
char general_info[23] = SVN_REVISION SERIAL_NUMBER SAMPLING_FREQUENCY SAMPLING_FREQUENCY; 

我該怎麼辦?

回答

1

如果你的意思是你要嵌入的16位整數500作爲字符串的結尾二進制數據,你可以使用原始十六進制字節:

/* Little-endian unsigned 16-bit integer with the value 500 */ 
#define SAMPLING_FREQUENCY "\xf4\x01" 

當心,雖然字節順序是架構相關的,所以你可能要添加一個額外的宏正確排序依賴於架構的字節:

#ifdef ... /* little endian */ 
#define BYTES2(a,b) b a 
#else ... /* big endian */ 
#define BYTES2(a,b) a b 
#endif 
#define SAMPLING_FREQUENCY BYTES16("x01", "\xf4") 

編輯:如果你想有一個人類可讀的數字,你不能把它在編譯時(至少在C),但你可以在運行時初始化:

#define SVN_REVISION  "1143" 
#define SERIAL_NUMBER "PST3201109270001" 
#pragma pack(push, 1) 
union { 
    struct { 
     char svn_rev_serial[20]; 
     uint16_t freq; 
     char nul; 
    }; 
    char general_info[23]; 
} u = {{ 
    SVN_REVISION SERIAL_NUMBER, 
    500, 
    '\0' 
}}; 
#pragma pack(pop) 

這使用更多的非標準(但良好支持)的結構,如#pragma pack和寫入一個聯盟成員和閱讀另一個。

+0

祝你好運,頻率爲512。 – themel

+0

+1關於字節數問題的警告 – pmg

+0

@themel,好吧,如果它已經指定了固定大小的二進制數據,*當然*它不會假定以NULL結尾的字符串... –

1

你必須使用通常的「stringify操作符」技巧。

#define STRINGIFY_HELPER(str) #str 
#define STRINGIFY(str) STRINGIFY_HELPER(str) 

#define SVN_REVISION   "1143" 
#define SERIAL_NUMBER   "PST3201109270001" 
#define SAMPLING_FREQUENCY (UINT16)500 
char general_info[23] = SVN_REVISION SERIAL_NUMBER SAMPLING_FREQUENCY STRINGIFY(SAMPLING_FREQUENCY); 

你需要雙宏利用預處理#運營商由於使用#操作時宏參數不展開。因此,首先需要額外的宏步驟來擴展參數,然後使用運算符#。一個很好的解釋可以找到here


編輯

其實,這不會因爲(UINT16)投,這也將被字符串化的工作。你仍然可以逃脫宏只能如果你能負擔得起創建一個額外的宏:

#define STRINGIFY_HELPER(str) #str 
#define STRINGIFY(str) STRINGIFY_HELPER(str) 

#define SVN_REVISION   "1143" 
#define SERIAL_NUMBER   "PST3201109270001" 
#define SAMPLING_FREQUENCY_NOCAST 500 
#define SAMPLING_FREQUENCY (UINT16)(SAMPLING_FREQUENCY_NOCAST) 
char general_info[23] = SVN_REVISION SERIAL_NUMBER SAMPLING_FREQUENCY STRINGIFY(SAMPLING_FREQUENCY_NOCAST); 

這是不是很優雅,但仍然避免重複500值的問題(你只需要更新它在一個地方,一切都會正常工作)。

+1

不會工作 - '( UINT16)'在字符串中會在詞彙上可見 –

+0

@ArmenTsirunyan:恩,沒錯,我沒有想到它。 –

+0

+1 stringify – Shahbaz

0

好了,你可以試試這個:

char general_info[23] = SVN_REVISION SERIAL_NUMBER SAMPLING_FREQUENCY; 
strcat(genral_info, itoa(SAMPLING_FREQUENCY)); 
+0

爲了安全起見,我建議'snprintf'(+'assert')而不是'strcat'。 –

0

Youy可以嘗試類似:

#define SVN_REVISION   "1143" 
#define SERIAL_NUMBER   "PST3201109270001" 
#define SAMPLING_FREQUENCY "\xF4\x1\00\00" 
char general_info[29] = SVN_REVISION SERIAL_NUMBER SAMPLING_FREQUENCY SAMPLING_FREQUENCY; 

\ XF4 \ X1 \ 00 \ 00,小數500內存表現形式(至少在Windows平臺上)