C语言 忽略使用sprintf显示数字



我有一个关于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开始的第二个循环将需要添加尾随空格。

相关内容

  • 没有找到相关文章

最新更新