使用%g的sprintf的最小缓冲区大小是多少?

2 c double printf

问题是静态分配一个足够大的缓冲区以适合打印的double,格式化为%g,最大精度.这似乎是一个足够简单的任务,我遇到了麻烦.我想出的最好的(假设要打印的数字是x)是

char buf[1 + DBL_DIG + DBL_DIG + 1 + 1 + 1 + DBL_DIG + 1];
int len = sprintf(buf, "%.*g", DBL_DIG, x);
Run Code Online (Sandbox Code Playgroud)

DBL_DIG宏来自float.h,显然它应该表示double类型的最大精度.我们需要:

  • 1个字节表示负号
  • 足够的字节来捕获有效数字
  • 每个数字最多一个'separator'字符(逗号等)
  • 小数点为1个字节
  • 'e'的1个字节
  • 指数上的符号为1个字节
  • 指数的一些字节
  • sprintf写入的尾部空值为1个字节.

我使用有效位数作为指数中位数的上限.我有任何错误吗?有更好的解决方案吗?我应该只分配64,128或256字节并希望最好吗?

pmg*_*pmg 5

使用snprintf()找出你有多少个字符需要:

#include <float.h> /* DBL_DIG */
#include <stdio.h>
#include <stdlib.h>

int main(void) {
  double x = rand() / (double)RAND_MAX;
  char find_len[1];
  int need_len;
  char *buf;

  need_len = snprintf(find_len, 1, "%.*g", DBL_DIG, x);
  buf = malloc(need_len + 1);
  if (buf) {
    int used = sprintf(buf, "%.*g", DBL_DIG, x);
    printf("need: %d; buf:[%s]; used:%d\n", need_len, buf, used);
    free(buf);
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

你需要一个C99编译器snprintf().
snprintf()由C99标准定义.C89实现不需要snprintf()定义,如果它具有扩展名,则不需要按照C99标准的描述"工作".


小智 5

您无法在编译时预先计算大小.%g格式化程序考虑了区域设置(对于1000的分隔符等).有关如何安全地计算大小的说明,请参阅http://linux.die.net/man/3/sprintf.