1

sprintf在嵌入式系统(Libelium Waspmote,类似于 Arduino)上遇到了一个奇怪的问题,其中 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

…<br> 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

4

3 回答 3

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 */
于 2013-03-04T12:53:14.910 回答
2

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

于 2013-03-04T12:46:05.273 回答
1

%02X 用于填充...它不会省略...因此,如果您的值大于指定值,则将打印整个字符串

于 2013-03-04T13:00:14.857 回答