将 C 中的 long 转换为 char* 最简单的方法是什么?

发布于 2024-09-04 08:06:52 字数 327 浏览 6 评论 0原文

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

What is the clean way to do that in 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;
}

The solutions I came up so far are all rather ugly, especially allocate_properly_size_whar_t uses double float base math.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

黑凤梨 2024-09-11 08:06:52

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 两次更快、更不容易出错,但代价是微不足道的堆栈空间。

A long won't have more than 64 digits on any platform (actually less than that, but I'm too lazy to figure out what the actual minimum is now). So just print to a fixed-size buffer, then use wcsdup rather than trying to calculate the length ahead of time.

wchar_t* ltostr(long value) {
    wchar_t buffer[ 64 ] = { 0 };
    swprintf(buffer, sizeof(buffer), L"%li", value);
    return wcsdup(buffer);
}

If you want a char*, it's trivial to translate the above:

char* ltostr(long value) {
    char buffer[ 64 ] = { 0 };
    snprintf(buffer, sizeof(buffer), "%li", value);
    return strdup(buffer);
}

This will be faster and less error-prone than calling snprintf twice, at the cost of a trivial amount of stack space.

狠疯拽 2024-09-11 08:06:52
int charsRequired = snprintf(NULL, 0, "%ld", value) + 1;
char *long_str_buffer = malloc(charsRequired);
snprintf(long_str_buffer, charsRequired, "%ld", value);
int charsRequired = snprintf(NULL, 0, "%ld", value) + 1;
char *long_str_buffer = malloc(charsRequired);
snprintf(long_str_buffer, charsRequired, "%ld", value);
同尘 2024-09-11 08:06:52

最大位数由 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() 的组合。

The maximum number of digits is given by ceil(log10(LONG_MAX)). You can precompute this value for the most common ranges of long using the preprocessor:

#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

Now, you can use

wchar_t buffer[LONG_MAX_DIGITS + 2];
int len = swprintf(buffer, sizeof buffer / sizeof *buffer, L"%li", -42l);

to get a stack-allocated wide-character string. For a heap-allocated string, use wcsdup() if available or a combination of malloc() and memcpy() otherwise.

奈何桥上唱咆哮 2024-09-11 08:06:52

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

Many people would recommend you avoid this approach, because it's not apparent that the user of your function will have to call free at some point. Usual approach is to write into a supplied buffer.

生生漫 2024-09-11 08:06:52

由于您收到一个 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:我会简化内存分配和释放比这个“工具箱”功能更多的内容。

Since you receive a long, you know it's range will be in –2,147,483,648 to 2,147,483,647 and since swprintf() uses locale ("C") by default (you control that part), you only need 11 characters. This saves you from string_size_of_long().

You could either (for locale 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;
 }

Or more general but less portable, you could use _scwprintf to get the length of the string required (but then it's similar to your original solution).

PS: I'd simplify the memory allocation and freeing more than this "tool-box" function.

指尖上得阳光 2024-09-11 08:06:52

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

#define MAX_SIZE(type) ((CHAR_BIT * sizeof(type)) / 3 + 2)

You can use the preprocessor to calculate an upper bound on the number of chars required to hold the text form of an integer type. The following works for signed and unsigned types (eg MAX_SIZE(int)) and leaves room for the terminating \0 and possible minus sign.

#define MAX_SIZE(type) ((CHAR_BIT * sizeof(type)) / 3 + 2)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文