将double转换为字符串而不分配超出要求的内存的正确方法?

问题描述 投票:0回答:3

我想知道正确的方法是什么也转换为未知值的双倍 尺寸 到没有分配太多内存的字符串。有没有办法弄清楚双倍的数字?我不想分配太多或太少的内存。

c string double
3个回答
5
投票

你可以使用NULL作为snprintf的第一个参数来获得大小:

C99允许str为NULL并且返回值(一如既往)为在输出字符串足够大的情况下写入的字符数。

然后malloc

int main(void)
{
    double num = 3.14;
    size_t len;
    char *str;

    len = (size_t)snprintf(NULL, 0, "%f", num) + 1;
    str = malloc(len);
    snprintf(str, len, "%f", num);
    puts(str);
    free(str);
    return 0;
}

4
投票

这里有一个基本的例子,当你只想知道表示的长度时如何使用snprintf

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main(void)
{
    int size = snprintf(NULL, 0, "%.15lf", M_PI);
    char *pi = malloc(size + 1);
    sprintf(pi, "%.15lf", M_PI);

    printf("PI: '%s'\n", pi);

    free(pi);
    return 0;
}

0
投票

将double转换为字符串而不分配超出要求的内存的正确方法?

使用snprintf()确定字符数需求。

double value = foo();
int size = snprintf(NULL, 0, some_format, value);
if (size < 0) Handle_encoding_error(); // This is very rare
else {
  char *buffer = malloc(size + 1u);
  if (buffer == NULL) Handle_OOM_error(); // This is also rare
  else {
    snprintf(buffer, 0, some_format, value);
    puts(buffer);
    free(buffer); 
  }
}

使用什么格式取决于编码目标。 "%f"经常导致许多大数据的无信息数字和大约一半"0.00000"double,因为许多数值小于0.0000005。

打印带有效数字的double的好方法是采用指数表示法。使用指数表示法的好处不仅是double被完全表达,它的最大字符串大小需要可以预先计算(大约28)并且不会过多。

通过使用指数表示法和DBL_DECIMAL_DIG - 1的精度打印,代码不需要更多的数字来将字符串“往返”返回到与doublestrtod()相同的sscanf()

"%a"    // Hexadecimal signicand
"%.*e"  // Decimal

int size = snprintf(NULL, 0, "%a", value);
// or 
int size = snprintf(NULL, 0, "%.*e", DBL_DECIMAL_DIG-1, value);

// or directly with minimal extra space
//         -   d   .    dddddd                 e   -  expo \0
#define N (1 + 1 + 1 + (DBL_DECIMAL_DIG - 1) + 1 + 1 + 6 + 1)
char buf[N]; 
snprintf(buf, sizeof buf, "%.*e", DBL_DECIMAL_DIG-1, value);

Printf width specifier to maintain precision of floating-point value

© www.soinside.com 2019 - 2024. All rights reserved.