我将分两部分回答你的问题。
你写道:
float number = 1245.12;
char number_as_string[50];
sprintf(number_as_string, "%f", number);
这样做是可以的,并且可以工作,但固定大小缓冲区的一个问题是很容易溢出,有时会造成灾难性的后果。因此,更好的选择是
snprintf(number_as_string, sizeof(number_as_string), "%f", number);
snprintf
是sprintf
的一种变体,可以让您指定缓冲区的大小。这样,snprintf
就能够确保不会将比缓冲区容量更多的字符写入缓冲区。
现在让我们看看如何使用snprintf
来处理您的第二个示例:
char *number_as_string;
snprintf(number_as_string, ???, "%f", number);
但是我们要用多大的尺寸呢?这个第二个 number_as_string
指向的缓冲区有多大?我们不知道,这让我们意识到我们还没有为第二个 number_as_string
分配指向的缓冲区。
你需要做的是使用 malloc
来为 number_as_string
分配一些内存空间:
number_as_string = malloc(50);
现在假设malloc
成功,你就知道要将什么数字作为缓冲区大小传递给snprintf
了:
snprintf(number_as_string, 50, "%f", number);
现实中,我们当然会有一个变量持有已分配缓冲区的大小,而不是在多个地方重复使用数字"50"。因此,这里是更加现实的示例,包括确保malloc
未失败的测试:
int buffer_size = 50;
char *number_as_string = malloc(buffer_size);
if(number_as_string == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
snprintf(number_as_string, buffer_size, "%f", number);
请务必避免以下行为:
snprintf(number_as_string, sizeof(number_as_string), "%f", number);
当
number_as_string
是一个指针时,您将获得指针的大小(通常为4或8个字节),而不是所指向的缓冲区的大小,这正是您想要的。
我喜欢用小盒子和箭头图来理解内存分配和指针。这里是
char number_as_string[50]
:
+
number_as_string: | | | | | | | | | | | | | |...| | |
+
以下是 char *number_as_string
和成功的 number_as_string = malloc(50)
:
+-------+
number_as_string: | * |
+---|---+
|
v
+--+--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+
| | | | | | | | | | | | | |...| | |
+--+--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+
但是这里只有char *number_as_string
:
+-------+
number_as_string: | *--------> ???
+-------+
箭头 - 指针 - 指向“无处”。
char number_as_string[50]; sprintf(number_as_string, "%f", number);
对于number = -DBL_MAX
也会失败。我怀疑你需要char number_as_string[DBL_MAX_10_EXP + 10];
或者类似的东西。 - chux - Reinstate Monica