2013-03-04 146 views
1

在嵌入式系统(Libelium Waspmote,类似于Arduino)中,我遇到了一个sprintf的奇怪问题,sprintf输出的字符数超过格式说明符给出的字符数。在这个特定的实例中,我使用%02X来输出数组中字节的十六进制值。然而,在一些字节中,不是写入2个字符,而是写入4个字符,其中FF在实际字节值之前加前缀。 snprintf的行为相似,只是它遵守指定的缓冲区大小并仅打印前缀。s(n)printf打印更多字符而不是格式说明符指定

作为参考,这里是代码片段打印数组内容:

char *pduChars = (char *) malloc(17*sizeof(char)); 
pduData.toChar(pduChars); 
for (int i = 0; i < 17; i++) { 
    char asciiCharsS[5]; 
    char asciiCharsSN[3]; 
    int printedS = sprintf(asciiCharsS, "%02X", pduChars[i]); 
    int printedSN = snprintf(asciiCharsSN, 3, "%02X", pduChars[i]); 
    USB.print(printedS); 
    USB.print(" "); 
    USB.print(printedSN); 
    USB.print(" "); 
    USB.print(asciiCharsS); 
    USB.print(" "); 
    USB.print(asciiCharsSN); 
    USB.println(" "); 
} 

,并从该段(删节仅将错误字节)的输出: 实际字节序列应为0x00 0xFC有0xFF的0xFF的0x48 0xA5和0x33 0x51

sprintf snprintf sprintf Buffer snprintf Buffer


2 2 00 00
4 4 FFFC FF
4 4 FFFF FF
4 4 FFFF FF
2 2 48 48
4 4 FFA5 FF
2 2 33 33
2 2 51 51

我在这里忽略了一些东西,或者这可能是与执行s(n)printf有关的平台特定问题?

+1

难道在你的平台上'char'是2个字节?请注意,'%02X'中的2是最小长度,而不是最大长度。 – Shahbaz 2013-03-04 12:48:12

+0

'sizeof(char)'返回'1',所以它似乎并非如此。 – 2013-03-04 13:01:26

+0

'sizeof(char)'总是一个。这是由标准定义的。但这并不意味着它是一个字节。实际上,'sizeof'没有给出字节数,它显示了相对于'char'大小的大小。 – Shahbaz 2013-03-04 13:09:27

回答

5

我猜你的实施是使用签署字符。格式"%X"预计值无符号值。改用Cast或使用unsigned char

/* cast */ 
int printedS = sprintf(asciiCharsS, "%02X", (unsigned char)pduChars[i]); 
int printedSN = snprintf(asciiCharsSN, 3, "%02X", (unsigned char)pduChars[i]); 

/* use unsigned char */ 
unsigned char *pduChars = malloc(17); /* cast is, at best, redundant */ 
             /* sizeof (char) is, by definition, 1 */ 
2

您正在使用的格式说明符修饰符仅用于填充。如果值的符号数超过指定值,则会打印整个字符串。

1

%02X是一个用来填充......它不会省略...... 这样的情况下,你的价值超过规定值,则整个字符串将在更大