当destation没有足够的空间时,使用`strcat()`的正确方法是什么?

问题描述 投票:1回答:3

man strcat说以下内容。

char *strcat(char *restrict s1, const char *restrict s2);

字符串s1必须有足够的空间来保存结果。

s1没有足够的空间时,处理这种情况的正确方法是什么?

c string strcat
3个回答
1
投票

如果s1没有足够的空间来容纳strlen(s1) + strlen(s2) + 1,尝试使用strcat(s1, s2)有不确定的行为。

strcat中没有内部检查s1的缓冲区溢出。如果你溢出,你溢出。但是,有一些特定于平台的替代方案,如果正确使用可以降低溢出的风险。作为Windows开发人员,我更喜欢StringCchCat中的StringCbCat<strsafe.h>

如果您想保证strcat的安全,您可以自己包装。就像是:

int safe_strcat(char *s1, char *s2, size_t s1_size)
{
    if (strlen(s1) + strlen(s2) + 1 > s1_size)
    {
        return 0;
    }
    strcat(s1, s2);
    return 1;
}

0
投票

strcat(s1, s2);可能导致溢出,因此预防措施“字符串s1必须有足够的空间来保存结果。”是有道理的。

假设s1可以持有N字符:N-1 non-'\0' + null字符。

当目的地没有足够的空间时,使用strcat()的正确方法是什么?

当串联可能溢出时,我看不到使用strcat()的应用程序。而是使用其他功能。


要检测潜在的溢出:

  1. 在通话前测试strlen(s1), strlen(s2)size_t l1 = strlen(s1); assert(l1 < N); // This really should be true already. N -= l1; size_t l2 = strlen(s2); if (l1 >= N) Handle_TooBigSomehow(); strcpy(s1 + l1, s2);
  2. 使用strncat(char * restrict s1, const char * restrict s2, size_t n)

请注意,这里的n不是Ns1可用的大小。

strncat函数在n指向的数组到s2指向的字符串末尾附加的s1字符(空字符及其后面的字符不会附加)不超过s2s1的初始字符会覆盖 size_t l1 = strlen(s1); assert(l1 < N); // This really should be true already. strncat(s1, s2, N - 1 - l1); // or faster strncat(s1 + l1, s2, N - 1 - l1); 末尾的空字符。终止空字符始终附加到结果。 C11§7.23.3.22

s1

不幸的是,没有明确的迹象表明空间不足,但至少没有溢出,qazxswpoi是空字符终止。


-1
投票

程序员有责任知道s1的大小。如果没有足够的空间,可以调用realloc(s1,num_of_bytes)来分配更多空间。

© www.soinside.com 2019 - 2024. All rights reserved.