我面对的是这个简单的"问题";实际上每天都有,但还没有一个好的解决方案:
char text[STRING_LENGTH + 1] = "";
int32_t number = -12312313;
itoa(number, text, 10); //or sprintf(text, "%d", number);
如何在预处理器中确定STRING_LENGTH
?STRING_LENGTH
应该是要转换的类型可能产生的最大长度。在我的情况下CCD_ 3=>11当然,我可以做这样的事情:
#define INT32_STRING_LENGTH 11
#define UINT32_STRING_LENGTH 10
//...
但似乎已经有了解决方案。
在这种情况下,也可以选择使用snprintf
,但这将在应用程序已经运行时计算长度。在运行时真的没有必要这样做(如果你有一些空闲字节(:
int32_t number = -12312313;
char text[snprintf(NULL, 0, "%d", number) + 1];
snprintf(text, sizeof(text), "%d", number);
也许有一个使用"%d"
、"%lu"
…的解决方案。。。?
如果我在这里提到的任何地方有错,请纠正我。
提前感谢!
GNU可移植性库有一个惊人的单头intprops
部分,其中有一些惊人的代码可从github/coreutils/gnulib/intprops.h获得。头包含INT_BUFSIZE_BOUND
和INT_STRLEN_BOUND
:
/* Bound on buffer size needed to represent an integer type or expression T,
including the terminating null. T must not be a bit-field expression. */
#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
文档中提供了带有使用示例的文档https://www.gnu.org/software/gnulib/manual/html_node/Integer-Bounds.html:
INT_BUFSIZE_BOUND(t(是一个整数常量表达式绑定到表示整数类型的字符串的大小,或者十进制表示法中的表达式t,包括终止的null角色和任何主角。例如,如果INT_BUFSIZE_BOUND(INT(是12,任何INT类型的值都可以是以12个字节或更少的字节表示,包括终止null。这个绑定不一定很紧。
示例用法:
#include <intprops.h> #include <stdio.h> int int_strlen (int i) { char buf[INT_BUFSIZE_BOUND (int)]; return sprintf (buf, "%d", i); }
请注意,标头是在GNU较宽松通用公共许可证下。请记住使用许可证复制标题,并使用一些贡献和许可证分发您的软件。然后只是:
int32_t number = -12312313;
char text[INT_BUFSIZE_BOUND(int32_t)];
// or [INT_BUFSIZE_BOUND(-12312313)];
sprintf(text, "%"PRId32, number);
注意,%d
可能对int32_t
无效。使用inttypes.h
中的标准PRId32
。
实现的核心是这个漂亮的函数,它可以用来基本上将数字的log10计算为常数表达式:
/* Bound on length of the string representing an unsigned integer
value representable in B bits. log10 (2.0) < 146/485. The
smallest value of B where this bound is not tight is 2621. */
#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)
因此,基本上要获得最大缓冲区大小长度,就要获得一个类型的位数,计算该位数的* 146 + 484) / 485)
,加上减号的+1
,加上零终止字节的+1
,这就是你需要的字节数。