【发布时间】:2017-01-30 05:18:39
【问题描述】:
在嵌入式编程中,我经常会得到如下所示的代码:
void debug_terminal_printf(const char* format, va_list ap){
char tmp[ARBITRARY_LIMITATION];
vsprintf( tmp, format, ap );
for(int pos=0; pos<strlen(tmp); pos++){
if( tmp[pos] == 0 ) break;
uart_putc( tmp[pos] );
}
}
我希望我的接口提供字符串格式的便利,但通常格式化字符串的消费者是一次使用几个字节的格式化字符串的东西,如本例中的 UART。所以我最终在我的每个辅助函数中都有这些小的临时缓冲区。使用动态内存并不是很合适,因为动态内存的使用是在系统级别做出的决定,在嵌入式平台代码中使用它是不合适的。
我希望能够做的是增量处理字符串,如下所示:
void debug_terminal_printf(const char* format, va_list ap){
char tmp[MAX_TOKEN_SIZE];
while(*format){
int len = single_token_sprintf( tmp, format, ap );
uart_puts(tmp);
format += len;
}
}
这样我就不需要足够的内存来存储整个格式化字符串,我可以等到硬件消耗完最后一个令牌,然后再继续解码下一个令牌。
有没有人见过像这样的(希望可移植的)习语,它可以摆脱对大型临时缓冲区的需求?
【问题讨论】:
-
在注意到您关于运行时间的评论后,我删除了该评论。但是,您是否对堆栈内存如此紧张以至于无法使用本地缓冲区?
-
通常串行访问可以通过
fopen()处理,即使在嵌入式中,fprintf()是一个选项吗? -
我认为没有任何方法可以便携。您需要一些方法来挂钩
stdio流的输出缓冲。 -
@weather-van。现在,使用堆栈正是我正在做的。然而这是一件非常粗鲁的事情,因为一个人可能想要使用“调试打印”从具有数十字节堆栈的上下文中打印微小的字符串,而其他人可能想要从另一个上下文中打印一个巨大的 1KB 字符串堆栈不是问题。在我的环境中,变量堆栈转换为对 malloc() 的文字调用,因此这不是一个选项。我可以让调用者明确地提供必要的暂存空间,但是在某些时候我的函数会从“帮助者”变为“阻碍者”。
-
可以处理寻找
"%"的format。如果使用的类型是像%d%s这样的小型子集,那么代码可以使用switch(format_specifier)处理调试打印一个参数一次
标签: c stream stdio standard-library format-specifiers