我有一个缓冲区,我正在做很多strncat。我想确保我永远不会溢出缓冲区大小。
char buff[64];
strcpy(buff, "String 1");
strncat(buff, "String 2", sizeof(buff));
strncat(buff, "String 3", sizeof(buff));
而不是sizeof(buff),我想说一些buff-xxx。我想确保我永远不会覆盖缓冲区
答案 0 :(得分:16)
考虑现有字符串和空终止符的大小
#define BUFFER_SIZE 64
char buff[BUFFER_SIZE];
//Use strncpy
strncpy(buff, "String 1", BUFFER_SIZE - 1);
buff[BUFFER_SIZE - 1] = '\0';
strncat(buff, "String 2", BUFFER_SIZE - strlen(buff) - 1);
strncat(buff, "String 3", BUFFER_SIZE - strlen(buff) - 1);
答案 1 :(得分:11)
为什么不使用snprintf
?与strncat
不同,它需要缓冲区的大小,但更重要的是,没有隐藏的O(n)。
Strcat需要在它连接的每个字符串上找到空终止符,并且每次都通过整个缓冲区来查找结束。每次字符串变长,strcat都会变慢。另一方面,Sprintf可以跟踪结束。你会发现
snprintf(buf, sizeof buf, "%s%s%s", "String1", "String2", "String3");
通常是一个更快,更易读的解决方案。
答案 2 :(得分:6)
在您的原始代码中使用strncat
函数的方式实际上适用于其他函数:strlcat
(注意l
而不是n
)。 strlcat
函数不是标准函数,但它是strncat
的常用实现替代函数。 strlcat
期望整个目标缓冲区的总大小作为其最后一个参数。
同时,strncat
期望目标缓冲区的剩余未使用部分的大小作为其第三个参数。因此,您的原始代码不正确。
我建议不要对strncpy
进行可怕的滥用,并使用strlen
调用进行明确的重新扫描(Joe的答案中都存在这两个问题),您要么使用提供的实现{{1或者自己实现一个(如果你的实现不提供strlcat
)。
答案 3 :(得分:3)
这是最好的方法。 sizeof()
只是给你指向数据的指针的大小,如果你不在本地分配它(在这种情况下你确实在本地进行了分配,但是这样做更好,如果代码被重新分解它会工作) 。
#define MAXBUFFSIZE 64
char buff[MAXBUFFSIZE];
buff[0] = 0; // or some string
strncat(buff, "String x",MAXBUFFSIZE - strlen(buff) - 1);
答案 4 :(得分:1)
strcat(...)
中的缓冲区溢出,你应该同样担心所有其他字符串函数中的缓冲区溢出。
使用strnlen(...)
和strncpy(...)
确保您保持在缓冲区内。如果您没有strnlen(...)
功能,请写下来。