使用 MACRO 将 sprintf 转换为 snprintf

标签 c printf

我们有一些如下代码:

#define MAXINT  1000000000

#define SPRINTF(a, b, c)    ((sizeof (a) > 8) ? snprintf(a, sizeof (a), b, c) : snprintf(a, MAXINT, b, c))
                            // avoids buffer overrun for static buffers of size > 8 else behaves like default sprintf()
                            // note max. size of char pointer is 8, so if sizeof (a) > 8, it means it is static array

我记得开发人员被要求将所有 sprintf() 转换为更安全的版本 snprintf(),他确实进行了如上所示的更改。

据我了解,上述宏仅针对大小 > 8 的静态缓冲区避免缓冲区损坏,而对于其他大小(即大小 <=8 的动态缓冲区和静态缓冲区),其行为类似于正常的 sprintf() ,假设被复制的字符串不大于“最大INT”。这是正确的吗?

例如。如果要复制的字符串小于 dest 缓冲区或大于 dest 缓冲区,则此语句/上面的 MACRO 将始终正确运行,如 snprintf(a, sizeof(a), b, c) 或正常默认 sprintf() - 这是一种暂时还可以。我假设它永远不会用 MAXINT (太大并且 src 字符串永远不会那么大)字符数量填充目标缓冲区?

最佳答案

该宏具有条件“a > 8”来检查 a 的类型是否为 char* 或 char[]。如果是 char*,则无法知道为其分配了多少内存以及可以写入多少内存。如果是 char[],那么我们确实知道为其保留了多少内存。因此,对于 char[],我们可以使用 snprintf,从而确保永远不会溢出,从而更加安全。对于 char*,我们无法提供相同的服务。该代码假设您永远不想写入超过 MAXINT 的内容。

如果我正在编写宏,我会将 snprintf(a, MAXINT, b, c) 更改为 sprintf(a, b, c),以更清楚地表明我们无法在这种情况下提供任何保证。

关于使用 MACRO 将 sprintf 转换为 snprintf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24115581/

相关文章:

c - 在c中连接字符串的最有效方法

c++ - wprintf 格式类型规范 %ws

c - 需要深入了解 printf 功能

c++ - 如何与nghttp2建立下载 channel ? (c/c++) (AVS)

c - 程序编译有错误

C++ 打印函数的结果?

c - C语言为什么不能有两个main函数呢?

c - C printf 中的 'I'(大写 i)标志是什么?

c - printf 在内部是如何工作的?

winapi - Lua 字符串不会连接