【问题标题】:Using snprintf to print an array? Alternatives?使用 snprintf 打印数组?备择方案?
【发布时间】:2013-06-05 13:55:21
【问题描述】:

是否可以使用snprintf 打印数组?我知道它可以接受多个参数,并且它期望至少与您的格式化字符串所建议的一样多,但是如果我只给它 1 个格式化字符串和一个值数组,它会将整个数组打印到缓冲区吗?

我问的原因是因为我正在修改源代码,而当前的实现只支持将一个值放在字符串中,但我正在修改它以支持一组值。我想尽可能少地改变原来的实现。

如果这不起作用,是否有人会推荐另一种方法来做到这一点?我应该把它吸起来并使用一个 for 循环(如果没有字符串缓冲区,这将如何真正有效)?

本质上:将双精度数组中的所有值放入同一个字符串以返回的最佳方法是什么?

【问题讨论】:

标签: c printf


【解决方案1】:

不,没有格式说明符。

当然,使用循环。您可以使用snprintf() 在其前面的一个之后打印每个双精度,因此您无需复制字符串:

double a[] = { 1, 2, 3 };
char outbuf[128], *put = outbuf;

for(int = 0; i < sizeof a / sizeof *a; ++i)
{
  put += snprintf(put, sizeof outbuf - (put - outbuf), "%f ", a[i]);
}

以上内容未经测试,但您大致了解。它用一个空格分隔每个数字,并且还会发出一个可能令人讨厌的尾随空格。

它并不能保护自己免受缓冲区溢出的影响,通常对于这样的代码,您可以知道输入的范围并确保outbuf 足够大。对于生产代码,您当然需要考虑这一点,这里的重点是展示如何解决核心问题。

【讨论】:

  • 它会自动追加缓冲区而不是覆盖它吗?
  • @Nealon 以上将追加,是的。请注意ptr 是如何用于指向字符串缓冲区中数字需要去的下一个位置,并随着我们的进行而递增。它通过使用snprintf() 的返回值来处理不同长度的字符串化双精度。
  • sizeof outbuf - (put - outbuf) -- 为什么这是必要的? sizeof ptr 不够吗?
  • @Nealon 它计算剩余字符数。不,sizeof ptr全错了,只是“指针ptr的大小”,在循环中是恒定的,与ptr指向的内存块大小无关。
  • 上面的代码不能防止缓冲区溢出。 snprintf 的第二个参数是一个无符号数 (size_t),这意味着如果这个参数是负数作为有符号数,它将被转换为一个大的无符号数,并可能造成缓冲区溢出。请注意,snprintf 不会返回实际写入的字节数,而是返回在有足够空间可用的情况下应该写入的字节数。
【解决方案2】:

我决定这样做:

int ptr = 0;
for( i = 0; i < size; i++)
{
    ptr += snprintf(outbuf + ptr, sizeof(outbuf) - ptr, "%.15f ", values[i]);   
}

略有不同,但效果与@unwind 的解决方案相同。我从reference pagesnprintf() 得到这个想法

【讨论】:

  • 上面的代码不能防止缓冲区溢出。 snprintf 的第二个参数是一个无符号数 (size_t),这意味着如果这个参数是负数作为有符号数,它将被转换为一个大的无符号数,并可能造成缓冲区溢出。请注意,snprintf 不会返回实际写入的字节数,而是返回在有足够空间可用的情况下应该写入的字节数。
猜你喜欢
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
  • 2011-12-08
  • 1970-01-01
相关资源
最近更新 更多