问题描述
我对C很陌生,当在C中处理long ints / char *时出现了一个问题。我想在char *中存储long,但是我不确定如何管理我的大小。缓冲区以适应任何长久的给定。 那就是我想要的:
char buffer[LONG_SIZE]; // what should LONG_SIZE be to fit any long,not depending on the OS?
sprintf(buffer,"%ld",some_long);
我需要使用C而不是C ++。如果我不想使用幻数,有什么解决方案吗?
解决方法
如果我不想使用幻数
将snprintf()
与长度为0的缓冲区一起使用将返回保存结果所需的字符数(减去结尾的0)。然后,您可以分配足够的空间来按需保留字符串:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(void) {
long some_long = LONG_MAX - 5;
// Real code should include error checking and handling.
int len = snprintf(NULL,"%ld",some_long);
char *buffer = malloc(len + 1);
snprintf(buffer,len + 1,some_long);
printf("%s takes %d chars\n",buffer,len);
free(buffer);
}
在Linux glibc和某些BSD中也有asprintf()
,可以为您分配结果字符串,并且界面比上述更方便(但移植性更差)。
按需分配所需的空间而不是使用固定的大小有一些好处;例如,如果将来在某个时候更改格式字符串,它将继续工作而无需进一步调整。
即使坚持使用固定长度的缓冲区,我还是建议在snprintf()
上使用sprintf()
,以确保不会以某种方式覆盖缓冲区。
使用snprintf
来计算必要的大小可能更正确,但这似乎应该可行:
char buf[ sizeof(long) * CHAR_BIT ];
,
long
中的位数为sizeof long * CHAR_BIT
。 (CHAR_BIT
在{{1}中定义。)这最多可以表示有符号数2 <limits.h>
。
这样的数字最多可以有下限(log 10 2 sizeof long * CHAR_BIT - 1
)+ 1个十进制数字。这是下限(sizeof long * CHAR_BIT - 1
* log 10 2)+1。log 10 2小于.302,因此(sizeof long * CHAR_BIT - 1)
* 302/1000 + 1个字节足以容纳数字。
为一个符号添加一个,为一个终止的空字符添加一个,并且(sizeof long * CHAR_BIT - 1)
足以满足缓冲区的需要。