在C语言中,有没有替代sprintf()函数的任何功能?编译后代码大小太大了。

9
我正在开发一个嵌入式系统(Cortex M3)。为了将设备上的一些数据发送到串行端口(显示在PC屏幕上),我使用了一些自己编写的函数,其中包括putchar()方法。
当我想发送整数或浮点数时,我使用sprintf()将它们转换为字符字符串,并将它们发送到串行端口。
现在,问题是我正在使用Keil uVision IDE,这是个限制版本,最大只支持32 KB。每次在不同的函数中调用sprintf()时,编译后的代码大小都会增加得很多,这让我困惑。我已经超过了32 KB,我想知道是否需要改变一些函数,并使用其他方法代替sprintf!
有什么线索吗?

7
尽可能避免使用float,因为它们的运行库组件在大多数情况下非常庞大且速度较慢。 - glglgl
1
printf家族的代价非常昂贵,因为实现它需要大量的代码,特别是浮点数。仅限整数的printf要小得多,但仍然很昂贵。你真的认为你需要在嵌入式微控制器代码中使用printf()吗?你可以实现自己更便宜的解决方案。 - old_timer
还要查看编译器供应商提供的可用库。通常会有多个版本的C标准库,其功能会被减少。例如,一个可以处理整数和浮点数但不能处理科学计数法的sprintf函数。 - Josh Petitt
3个回答

9

有两个可能的选择(我自己都没有使用过——我的编译器供应商通常会提供一个简化的用于嵌入式系统的 printf 函数):

http://eprintf.sourceforge.net/ — [2017年9月:不幸的是,该网站似乎已经消失了,但源代码仍在这里:https://sourceforge.net/projects/eprintf/files/]。

http://www.sparetimelabs.com/tinyprintf/index.html — 2个文件,大约1.4KB代码。支持启用“longs”(代表更多的代码量)。能够支持前导零和字段宽度。不支持浮点数。


1
由于“eprintf”网页没有指向实际代码的链接,因此在此提供SourceForge“eprintf”项目的链接:http://sourceforge.net/projects/eprintf/。 - Michael Burr
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅链接的答案可能会失效。-【来自审查】 - StoryTeller - Unslander Monica
@StoryTeller - 通常我会同意,但如果链接失效(就像我看到其中一个已经失效了:(),那么内容摘要并没有什么帮助,因为我只是提供源代码的链接而不是真正的“答案”。 - Martin Thompson

8
如果您想让它更有效率,最好的方法可能是自己编写代码或在网络上寻找已经编写好的代码。将整数转换为字符串非常简单,每个程序员都可以在不到30分钟内编写出来。将浮点数转换为字符串则稍微复杂一些,这取决于所使用的浮点格式。
为了方便起见,在此提供一个用于微控制器应用的简单整数转字符串算法:
void get_dec_str (uint8_t* str, size_t len, uint32_t val)
{
  uint8_t i;
  for(i=1; i<=len; i++)
  {
    str[len-i] = (uint8_t) ((val % 10UL) + '0');
    val/=10;
  }

  str[i-1] = '\0';
}

2
如果你的微控制器没有硬件除法器(或模数),我不确定这是否是一个非常快速/高效的函数...尽管我目前脑海中没有更好的选择! - Martin Thompson
3
@MartinThompson,我不确定有什么办法可以解决这个问题,因为十进制是基于十的,但计算机更喜欢基于2/4/8/16/32的数字。另外,我宁愿让编译器来进行优化。 - Lundin
1
公正的评论:将优化留给编译器。 - Martin Thompson

0
你可以尝试使用 itoa() 或者 ftoa(),并根据需要实现它们。我的意思是,在定义内部将它们转换为字符后,直接使用 putchar() 将其打印出来。
我认为这样应该能够正常工作。

5
在C语言中,没有名为itoa或ftoa的函数。 - Lundin
@Lundin:可以按照您的需求编写代码...或者包括这些文件...itoa和ftoa位于头文件< stdlib.h >或< cstdlib >中。 - Omkant
C语言中没有itoa()和ftoi()函数。(我不知道它们是否存在于C++中) - Django
@Omkant,它们不在stdlib中,因为它们不是任何C或C++标准的一部分。您正在使用某些非标准编译器。 - Lundin
@Lundin:正如我之前提到的,你可以实现相同的...这意味着编写自己的定义。 - Omkant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接