2011-09-28 64 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平台上)