在C中干净的方法是什么?
wchar_t* ltostr(long value) {
int size = string_size_of_long(value);
wchar_t *wchar_copy = malloc(value * sizeof(wchar_t));
swprintf(wchar_copy, size, L"%li", self);
return wchar_copy;
}
到目前为止我提出的解决方案都非常难看,特别是allocate_properly_size_whar_t使用双浮点基数学。
答案 0 :(得分:4)
long
在任何平台上的数字都不会超过64位(实际上比这还少,但是我太懒了,无法弄清楚现在的实际最小值)。因此,只需打印到固定大小的缓冲区,然后使用wcsdup
而不是尝试提前计算长度。
wchar_t* ltostr(long value) {
wchar_t buffer[ 64 ] = { 0 };
swprintf(buffer, sizeof(buffer), L"%li", value);
return wcsdup(buffer);
}
如果你想要一个char*
,翻译上面的内容是微不足道的:
char* ltostr(long value) {
char buffer[ 64 ] = { 0 };
snprintf(buffer, sizeof(buffer), "%li", value);
return strdup(buffer);
}
这比调用snprintf
两次更快,更不容易出错,代价是占用了大量的堆栈空间。
答案 1 :(得分:3)
int charsRequired = snprintf(NULL, 0, "%ld", value) + 1;
char *long_str_buffer = malloc(charsRequired);
snprintf(long_str_buffer, charsRequired, "%ld", value);
答案 2 :(得分:2)
最大位数由ceil(log10(LONG_MAX))
给出。您可以使用预处理器预先计算此long
范围的值:
#include <limits.h>
#if LONG_MAX < 1u << 31
#define LONG_MAX_DIGITS 10
#elif LONG_MAX < 1u << 63
#define LONG_MAX_DIGITS 19
#elif LONG_MAX < 1u << 127
#define LONG_MAX_DIGITS 39
#else
#error "unsupported LONG_MAX"
#endif
现在,您可以使用
wchar_t buffer[LONG_MAX_DIGITS + 2];
int len = swprintf(buffer, sizeof buffer / sizeof *buffer, L"%li", -42l);
获取堆栈分配的宽字符串。对于堆分配的字符串,如果可用,请使用wcsdup()
,否则使用malloc()
和memcpy()
的组合。
答案 3 :(得分:1)
很多人会建议你避免使用这种方法,因为你的功能用户不一定要在某个时候调用free
。通常的做法是写入提供的缓冲区。
答案 4 :(得分:0)
由于你得到一个长的,你知道它的范围是-2,147,483,648到2,147,483,647,并且由于swprintf()默认使用locale(“C”)(你控制那个部分),你只需要11个字符。这样可以使您免于string_size_of_long()
。
你可以(对于语言环境C):
wchar_t* ltostr(long value) {
wchar_t *wchar_copy = malloc(12 * sizeof(wchar_t));
swprintf(wchar_copy, 12, L"%li", value);
return wchar_copy;
}
或者更通用但不太便携,您可以使用_scwprintf
来获取所需字符串的长度(但它与原始解决方案类似)。
PS:我会简化内存分配并释放超过这个“工具箱”功能。
答案 5 :(得分:0)
您可以使用预处理器计算保存整数类型的文本形式所需的char
个数的上限。以下适用于有符号和无符号类型(例如MAX_SIZE(int)
),并为终止\0
和可能的减号留出空间。
#define MAX_SIZE(type) ((CHAR_BIT * sizeof(type)) / 3 + 2)