确定 char 数组的大小以使用预处理器转换数字
Determine size of char array to convert numbers with the preprocessor
我每天都在面对这个简单的“问题”,但还没有好的解决方案:
char text[STRING_LENGTH + 1] = "";
int32_t number = -12312313;
itoa(number, text, 10); //or sprintf(text, "%d", number);
如何在预处理器中确定 STRING_LENGTH
? STRING_LENGTH
应该是要转换的类型可以产生的最大长度。在我的例子中 int32_t
=> 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"
、...的解决方案?
如果我在这里提到的任何地方有误,请纠正我。
提前致谢!
The GNU Portability Library has an amazing single header intprops
part which has some amazing code available from github/coreutils/gnulib/intprops.h。 header 包含 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) is an integer constant expression that is a
bound on the size of the string representing an integer type or
expression t in decimal notation, including the terminating null
character and any leading - character. For example, if
INT_BUFSIZE_BOUND (int) is 12, any value of type int can be
represented in 12 bytes or less, including the terminating null. The
bound is not necessarily tight.
Example usage:
#include <intprops.h>
#include <stdio.h>
int
int_strlen (int i)
{
char buf[INT_BUFSIZE_BOUND (int)];
return sprintf (buf, "%d", i);
}
请注意 header 在 GNU Lesser General Public 许可证下。请记住复制 header with license 并通过一些贡献和许可分发您的软件。然后:
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
对于零终止字节 - 这是您需要的字节数。
我每天都在面对这个简单的“问题”,但还没有好的解决方案:
char text[STRING_LENGTH + 1] = "";
int32_t number = -12312313;
itoa(number, text, 10); //or sprintf(text, "%d", number);
如何在预处理器中确定 STRING_LENGTH
? STRING_LENGTH
应该是要转换的类型可以产生的最大长度。在我的例子中 int32_t
=> 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"
、...的解决方案?
如果我在这里提到的任何地方有误,请纠正我。
提前致谢!
The GNU Portability Library has an amazing single header intprops
part which has some amazing code available from github/coreutils/gnulib/intprops.h。 header 包含 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) is an integer constant expression that is a bound on the size of the string representing an integer type or expression t in decimal notation, including the terminating null character and any leading - character. For example, if INT_BUFSIZE_BOUND (int) is 12, any value of type int can be represented in 12 bytes or less, including the terminating null. The bound is not necessarily tight.
Example usage:
#include <intprops.h> #include <stdio.h> int int_strlen (int i) { char buf[INT_BUFSIZE_BOUND (int)]; return sprintf (buf, "%d", i); }
请注意 header 在 GNU Lesser General Public 许可证下。请记住复制 header with license 并通过一些贡献和许可分发您的软件。然后:
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
对于零终止字节 - 这是您需要的字节数。