c strncpy null是否终止
我正在读一份文件,上面写着: 从字符串复制字符 将c strncpy null是否终止,c,strncpy,C,Strncpy,我正在读一份文件,上面写着: 从字符串复制字符 将源的第一个num字符复制到目标。如果在复制num字符之前找到sourceC字符串(由空字符表示)的结尾,则destination用零填充,直到总共写入num字符 如果源长度大于num,则不会在目标的末尾隐式追加空字符。因此,在这种情况下,目的地不应被视为以null结尾的C字符串(这样读取会溢出) 目的地和源不得重叠(请参见memmove了解重叠时更安全的替代方案) 但我对这种说法感到困惑: 在这种情况下,目的地不应被视为以null结尾的C字符串(
源
的第一个num
字符复制到目标
。如果在复制num
字符之前找到source
C字符串(由空字符表示)的结尾,则destination
用零填充,直到总共写入num
字符
如果源长度大于num
,则不会在目标的末尾隐式追加空字符。因此,在这种情况下,目的地
不应被视为以null结尾的C字符串(这样读取会溢出)
目的地
和源
不得重叠(请参见memmove
了解重叠时更安全的替代方案)
但我对这种说法感到困惑:
在这种情况下,目的地不应被视为以null结尾的C字符串(这样读取会溢出)
既然num>strlen(source)
,它将在末尾填充'\0'
,'\0'
实际上是字符串中的空(终止)字符,为什么不应将其视为空终止的C字符串
我编写了以下代码来验证:
char from[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
char to[1024];
for (int i = 0; i < 1024; i++) {
to[i] = 'e';
}
strncpy(to, from, 1024);
printf("from %s\n", from);
它讨论的是当strlen(源代码)
num
时的情况。它将只复制num
字符,其中没有一个是NUL,也不会添加NUL。strncpy(dst,src,len)
如果src
中的第一个len
字节中存在空终止符,则只向dst
添加空终止符。您的代码似乎可以工作,因为数组到[]
之后可能有空字符,也可能没有空字符。更好的测试是:
char source[] = "source";
char dest[] = "destination";
strncpy(dest, source, 6);
printf("%s\n", dest);
结果应该是:
sourceation
如果你写的是代码> STRNCPY(Dist,Soad,7),那么输出就是“代码>代码源。
< P> >代码> STRNCYP()/<代码>,即使在上面的C++引用中被精确解释时,也被广泛误解。此函数的行为违反直觉且容易出错 为了避免在使用它或在开发过程中出现问题,当维护人员误读代码并添加更多微妙的错误时,有一个简单的解决方案:永远不要使用这个函数 您可以在中阅读有关此的更多详细信息回答您的问题:如果源字符串长于作为第三个参数传递的大小(通常对应于目标缓冲区的大小),则函数会将大小字符复制到目标,并且这些字符之间不存在空字节。呼叫
strlen(目的地)
随后将调用未定义的行为,因为它将尝试读取数组末尾以外的内容,直到找到空终止符。这种特殊的行为使得strncpy很容易出错。strncpy
:不要使用它。缺少'\0'
就是strlen(source)>num,所以我想你只是有一个简单的误解-试试strncpy(to,from,2)代码>改为:我更新了答案。阻止新手使用这个容易出错的函数是很重要的。我见过很多误用的例子,即使是有经验的程序员。。。它充当一个通用的bug吸引器。这是现在最好的答案。很遗憾,从不使用此函数不能在红色和黑色之间闪烁。我会将strtok、atoi、atof和整个scanf系列添加到要避免的函数列表中。@EvilTeach:我同意strtok
和scanf
atoi
和atof
不提供错误检查,但问题小得多feof()
在列表中的位置也很高,sprintf()
应替换为snprintf()
,char
默认为无符号,强制使用2s补码,以及8/16/32/和64位整数类型,IEEE浮点。。。这将使C变得更简单。@EvilTeach:feof()
几乎被系统地误用在中,而(!feof(fp))
<默认情况下带符号的code>char
与返回unsigned char
类型加上EOF
,strcmp()的值不一致
比较字符串作为无符号字符的数组和
中调用未定义行为的函数作为负char
值的数组……为了确保得到NUL终止符,请使用strlcpy
而不是strncpy
。
char source[] = "source";
char dest[] = "destination";
strncpy(dest, source, 6);
printf("%s\n", dest);
sourceation