1

在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 使用双浮点基础数学。

4

6 回答 6

4

Along在任何平台上都不会超过 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两次更快且更不容易出错,但代价是微不足道的堆栈空间。

于 2010-06-08T16:06:47.763 回答
3
int charsRequired = snprintf(NULL, 0, "%ld", value) + 1;
char *long_str_buffer = malloc(charsRequired);
snprintf(long_str_buffer, charsRequired, "%ld", value);
于 2010-06-08T16:09:04.173 回答
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()

于 2010-06-08T18:58:13.693 回答
1

许多人会建议您避免使用这种方法,因为您的函数的用户free在某些时候必须调用并不明显。通常的方法是写入提供的缓冲区。

于 2010-06-08T16:12:36.353 回答
0

由于您收到 long,您知道它的范围将在 –2,147,483,648 到 2,147,483,647 之间,并且由于 swprintf() 默认使用语言环境(“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:我会简化内存分配和释放比这个“工具箱”功能更多的东西。

于 2010-06-08T16:16:26.317 回答
0

char您可以使用预处理器计算保存整数类型文本形式所需的 s数的上限。以下适用于有符号和无符号类型(例如MAX_SIZE(int)),并为终止\0和可能的减号留出了空间。

#define MAX_SIZE(type) ((CHAR_BIT * sizeof(type)) / 3 + 2)
于 2010-06-09T00:33:20.887 回答