如何在没有缓冲区溢出问题的情况下使用strncat?

我有一个缓冲区,我正在做很多strncat。 我想确保我永远不会溢出缓冲区大小。

char buff[64]; strcpy(buff, "String 1"); strncat(buff, "String 2", sizeof(buff)); strncat(buff, "String 3", sizeof(buff)); 

而不是sizeof(buff),我想说一些buff – xxx。 我想确保我永远不会覆盖缓冲区

考虑现有字符串和null终止符的大小

 #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); 

为什么不使用snprintf ? 与strncat不同,它需要缓冲区的大小,但更重要的是,没有隐藏的O(n)。

Strcat需要在它连接的每个字符串上找到空终止符,并且每次都通过整个缓冲区来查找结束。 每次字符串变长,strcat都会变慢。 另一方面,Sprintf可以跟踪结束。 你会发现的

 snprintf(buf, sizeof buf, "%s%s%s", "String1", "String2", "String3"); 

通常是一个更快,更易读的解决方案。

在你的orignal代码中使用strncat函数的方式实际上适用于另一个函数: strlcat (注意l而不是n )。 strlcat函数不是标准函数,但它是strncat一个流行的实现提供的替代品。 strlcat期望整个目标缓冲区的总大小作为其最后一个参数。

同时, strncat期望将目标缓冲区的剩余未使用部分的大小作为其第三个参数。 因此,您的原始代码不正确。

我建议不要使用strncpy这种可怕的滥用并使用strlen调用进行显式重新扫描(Joe的答案中都存在这两个问题),你要么使用实现提供的strlcat要么自己实现(如果你的实现没有提供strlcat )。

http://en.wikipedia.org/wiki/Strlcpy

这是最好的方法。 sizeof()只是给你指向数据的指针的大小,如果你不在本地分配它(在这种情况下你确实在本地分配,但最好这样做,如果代码被重新分解它将起作用)。

 #define MAXBUFFSIZE 64 char buff[MAXBUFFSIZE]; buff[0] = 0; // or some string strncat(buff, "String x",MAXBUFFSIZE - strlen(buff) - 1); 

霍根已经足够满满地回答了这个问题; 但是,如果你担心strcat(...)缓冲区溢出,你应该同样担心所有其他字符串函数中的缓冲区溢出。

使用strnlen(...)strncpy(...)来确保您保持在缓冲区内。 如果您没有strnlen(...)函数,请编写它。