将整数转换为文本时,通常我会创建一个大缓冲区sprintf()
来保存任何潜在的结果。
char BigBuffer[50];
sprintf(BugBuffer, "%d", SomeInt);
我想更节省空间,当然也更便携,所以不是 ,而是50
找到了替代方案:
(sizeof(integer_type)*CHAR_BIT*0.302) + 3
// 0.0302 about log10(2)
#define USHORT_DECIMAL_BUFN ((size_t) (sizeof(unsigned short)*CHAR_BIT*0.302) + 3)
#define INT_DECIMAL_BUFN ((size_t) (sizeof(int) *CHAR_BIT*0.302) + 3)
#define INTMAX_DECIMAL_BUFN ((size_t) (sizeof(intmax_t) *CHAR_BIT*0.302) + 3)
int main() {
char usbuffer[USHORT_DECIMAL_BUFN];
sprintf(usbuffer, "%hu", USHRT_MAX);
printf("Size:%zu Len:%zu %s\n", sizeof(usbuffer), strlen(usbuffer), usbuffer);
char ibuffer[INT_DECIMAL_BUFN];
sprintf(ibuffer, "%d", INT_MIN);
printf("Size:%zu Len:%zu %s\n", sizeof(ibuffer), strlen(ibuffer), ibuffer);
char imbuffer[INTMAX_DECIMAL_BUFN];
sprintf(imbuffer, "%" PRIdMAX, INTMAX_MIN);
printf("Size:%zu Len:%zu %s\n", sizeof(imbuffer), strlen(imbuffer), imbuffer);
return 0;
}
Size:7 Len:5 65535
Size:12 Len:11 -2147483648
Size:22 Len:20 -9223372036854775808
所以问题是:
1 替代方程有问题吗?
2 有什么更好的解决方案?- 因为这种替代方案有点浪费,而且看起来过于复杂。
[编辑答案]
答案提供了 3 种深思熟虑的方法:
1 使用缓冲区[类型的最大大小] (已选择答案)
2 asprintf()
3snprintf()
1 使用方程式的编译时间最大缓冲区大小(sizeof(integer_type)*CHAR_BIT*0.302) + 3
没有被破坏或改进。的影响<locale.h>
已按照@paddy 的建议进行了研究,并且没有区域设置影响整数转换%d %x %u %i
。发现如果类型已知为有符号或无符号(如下),则可以对等式进行轻微改进。@paddy 关于“更保守”的警告是个好建议。
2asprintf()
确实是一个很好的通用解决方案,但不便携。也许在 C11 后?
3 snprintf()
,虽然是标准的,但在提供的缓冲区过小时已知一致的实现问题。这意味着用一个过大的缓冲区调用它,然后生成一个正确大小的缓冲区。@jxh 建议使用线程安全的全局暂存缓冲区来使用本地大小合适的缓冲区形成答案。这种新颖的方法值得我考虑使用,但最初的问题更侧重于在s(n)printf()
调用之前确定保守的缓冲区大小。
signed ((sizeof(integer_type)*CHAR_BIT-1)*0.302) + 3
unsigned (sizeof(integer_type)*CHAR_BIT*0.302) + 2
*28/93
可以用来代替*0.302
。