我有一个关于C函数sprint的问题。它是可能的,显示十六进制数字只有如果一些情况还好吗?还是打印一些空白?
DLC是数据长度,例如,如果DLC = 2,我只想打包2个数据字节来缓冲,其他6个字节需要被忽略或用空格替换。
sprintf(buffer, "%02X %02X %02X %02X %02X %02X %02X %02X",
(frame.frameDLC > 0)? frame.frameData[0]:" ", (frame.frameDLC > 1) ? frame.frameData[1] : " ",
(frame.frameDLC > 2) ? frame.frameData[2] : " ", (frame.frameDLC > 3) ? frame.frameData[3] : " ",
(frame.frameDLC > 4) ? frame.frameData[4] : " ", (frame.frameDLC > 5) ? frame.frameData[5] : " ",
(frame.frameDLC > 6) ? frame.frameData[6] : " ", (frame.frameDLC > 7) ? frame.frameData[7] : " ",
);
对于嵌入式系统,您确实希望避免像sprintf
这样臃肿的库函数,因为它占用了大量的执行时间和内存。在专业环境中使用这个功能是完全不可接受的。类似地,在中高档系统上,您将希望避免像?:
示例那样的大量分支。
手工转换非常简单,比sprintf快10到100倍,具体取决于系统:
#include <stdio.h>
#include <stdint.h>
typedef struct
{
uint8_t data[8];
uint8_t dlc;
} frame_t;
static inline char hex_nibble (uint8_t bin)
{
return "0123456789ABCDEF"[bin];
}
int main (void)
{
char buf [100];
size_t length=0;
frame_t frame = { .data={0xAA,0xBB,0x55,0x77}, .dlc=4 };
for(uint8_t i=0; i<frame.dlc; i++)
{
buf[length++] = hex_nibble(frame.data[i]>>4&0xF);
buf[length++] = hex_nibble(frame.data[i]&0xF);
}
buf[length]=' ';
puts(buf);
}
如果你想在数字后面加空格,只需做第二次循环:
for(uint8_t i=frame.dlc; i<8; i++)
{
buf[length++] = ' ';
buf[length++] = ' ';
}
禁止使用sprintf
。使用边界检查snprintf
代替。
是否有可能,仅在某些条件OK时显示十六进制数?还是打印一些空白?
是的,使用if
。基本上你的代码是一个for循环…
char buffer[200];
size_t pos = 0;
for (size_t i = 0; i < frame.frameDLC; ++i) {
pos += snprintf(&buffer[pos], sizeof(buffer) - pos, "%02X", frame.frameData[i]);
}
for (size_t i = frame.frameDLC; i < 8; ++i) {
pos += snprintf(&buffer[pos], sizeof(buffer) - pos, " ");
}
sprint()
返回输出的字符数。您可以使用它来维护"光标位置"。在缓冲区中以增量方式输出每个元素。
int bi = 0 ;
for( int di = 0; di < frame.frameDLC; di++ )
{
bi += sprintf( &buffer[bi], "%02X", frame.frameData[di] ) ;
if( di + 1 < frame.frameDLC)
{
bi += sprintf( &buffer[bi], " ", frame.frameData[di] ) ;
}
}
以上假设每个元素之间有两个空格,并且不希望/不需要尾随空格。
如果你不关心末尾空格,它可以简化为:
int bi = 0 ;
for( int di = 0; di < frame.frameDLC; di++ )
{
bi += sprintf( &buffer[bi], "%02X ", frame.frameData[di] ) ;
}
如果你的问题中第5和第6之间的空格是故意的,那么你可能需要:
if( di + 1 < frame.frameDLC)
{
bi += sprintf( &buffer[bi],
di == 4 ? " " :" ",
frame.frameData[di] ) ;
}
如果您确实需要将字符串空格填充到29个字符(就像您问题中的代码所做的那样),那么从bi
开始的第二个循环将需要添加尾随空格。