我在嵌入式系统(Libelium Waspmote,类似于Arduino)上遇到sprintf
的奇怪问题,其中sprintf输出的字符多于格式说明符给出的字符。在这个特定的实例中,我使用%02X
输出数组中十六进制的字节值。但是在某些字节上,不是写入2个字符,而是写入4个字符,FF
在实际字节值之前加上前缀。 snprintf
的行为类似,只是它遵守指定的缓冲区大小并只打印前缀。
供参考,以下是打印数组内容的代码片段:
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
的实施相关的特定于平台的问题?
答案 0 :(得分:5)
我猜你的实施正在使用签名字符。格式"%X"
需要无符号值。转而使用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 */
答案 1 :(得分:2)
您使用的格式说明符修饰符仅用于填充。如果值的符号数超过指定值,则将打印整个字符串。
答案 2 :(得分:1)
%02X用于填充...它不会省略... 因此,如果您的值大于指定值,则将打印整个字符串