我多次使用strncat
,但现在只检查标准中的正式定义:
#include <string.h>
char *strncat(char * restrict s1,
const char * restrict s2,
size_t n);
strncat函数从s2指向的数组到s1指向的字符串末尾追加不超过n个字符(空字符及其后面的字符不会被追加)。 s2的初始字符将覆盖s1末尾的空字符。终止空字符始终附加到结果中。
通常,我会将s1
和s2
简单地视为char的指针。但正如所看到的,该标准对它们的要求不同:
s1
s2
s1
和s2
之间的唯一区别是const限定符 - 这就是为什么一个被称为数组而另一个被称为字符串
此外,在脚注中:
因此,s1指向的数组中可以结束的最大字符数是strlen(s1)+ n + 1.
所以这里他们以不同的方式引用s1
:s1
指向的数组(不是字符串)
这些不同的方式调用s1
和s2
是否有任何暗示?
答案 0 :(得分:16)
s1和s2之间的唯一区别是const限定符
不,不一定。
目标数组s1
必须已经以空值终止。因此,它可以安全地称为字符串。
引用C11
,章节§7.1.1/ p1,术语定义
string 是由第一个null终止并包含第一个null的连续字符序列 字符。 [...]
但是,对于源数组s2
,如果给定大小n
小于实际长度,则null终止不是必须数组。所以,必须不是字符串,总是。
所以, TL; DR - 目的地数组总是字符串(因此可以互换使用)但是没有这样的保证对于源数组。
另外,为了突出显示用法中的差异,我们将其与strcat()
的描述进行比较,s2
具有相似的语法,减去大小。因此,两个参数都需要以null结尾,因为没有其他方法可以让函数确定 source 数组strcat
的结尾。因此,请注意那里的措辞(强调我的),来自章节§7.24.3.1
s2
函数附加s1
指向的字符串的副本(包括 终止空字符)到s2
指向的字符串的末尾。最初的角色s1
的覆盖范围覆盖SELECT * FROM `Contacts` WHERE `Zona` = '1' AND `Responsable` = '9' AND `AllowComercialVisit` = 'Call_Again' -- the problem are OR's -- OR `AllowComercialVisit` = 'Busy' OR `AllowComercialVisit` = 'Not_answered' -- the problem are OR's -- AND `DateRecall` <= '2016-06-20 13:04:52' AND `DateRecall` >= '2016-06-20 12:39:52' ORDER BY `DateRecall` ASC LIMIT 1
末尾的空字符。如果在之间进行复制 重叠的对象,行为未定义。
这里,两个数组必须是字符串,因此是用法。
答案 1 :(得分:4)
在C中,字符串为NUL
- 已终止,其中数组不是(必需)。这就是这个函数采用n
参数的原因;因为s2
不一定是NUL
- 已终止。
答案 2 :(得分:2)
数组是存储区域。 string 是一个特殊的字符序列(以空终止符结尾),可以存储在数组中。
char
数组在任何特定时间都可能包含或不包含字符串。
(尽管已经有几个答案,我仍在发帖,因为其他答案并未使容器包含的关系明确。)
使用strncat
函数,第一个参数必须指向包含字符串的数组中的字符(我们说“指向字符串”);但由于第二个参数可能是长度计数的,因此它可以指向数组中不包含字符串的字符。