strncpy()的示例

lawou6xi  于 2022-12-22  发布在  其他
关注(0)|答案(4)|浏览(109)

如果我对字符串catdog使用strncpy函数,我不知道\0字符是否被计算在内,所以我想知道最终结果是catdo还是类似cat\0do
strncpy("cat", "dog", 2);

i86rm4rw

i86rm4rw1#

根本不应使用strncpystrncat函数。
它们的名字以str开头,但它们实际上并不处理字符串。在C中,字符串被定义为“以'\0'结尾的字符序列“。这些函数并不保证得到的字符数组总是以null结尾。
更好的替代方案是strlcpystrlcat,但它们并不是到处都可用。
更好的办法是建立一个独立的字符串库,在其中确定字符串的长度是一个恒定时间的操作,但这会分散注意力。

ldioqlga

ldioqlga2#

正如torstenvl提到的,"cat""dog"是字符串常量,所以这里没有正确使用函数,第一个参数是destination,第二个参数是source,第三个参数是要复制的字节数。

char *strncpy(char *restrict s1, const char *restrict s2, size_t n)

来源:开放组基础规范- strncpy
要回答您的具体问题:是;空终止符被复制到目标字符串。n字节被写入,并且如果你的源字符串s2n字节短,NULL被填充直到n字节被写入。
在你的问题中,看起来像是你在尝试追加两个字符串。要在C语言中这样做,你需要首先分配一个源字符串缓冲区,复制第一个字符串,然后从第二个字符串的末尾开始复制第二个字符串。根据你最后一步的开始位置,你可以得到“catdog\0”或者“cat\0dog\0”。2这是典型的“off by one”错误的另一个例子。
首先,你必须计算两个你想要追加的字符串的长度,你可以使用strlen,from string.h来计算。strlen把空终止符作为长度的一部分,所以记住,要得到最后一个字符串的长度,你必须使用strlen(s1) + strlen(s2) + 1
然后你可以像往常一样复制第一个字符串。复制第二个字符串的一个简单方法是这样做:

char* s2start = finalString[strlen(s1) + 1];

然后,您可以执行strncpy(s2start, s2, [the size of s2]),这样您就知道您是从s1空终止符开始的,从而避免了“cat\0dog”错误。
希望这能帮上忙,祝你好运。

vwoqyblh

vwoqyblh3#

当你在c中写出一个像"cat""dog"这样的字符串时,数组是不能改变的,如果你试图改变它会导致未定义的行为。你只能在一个函数需要const char * input时使用这些数组,const告诉你它不能/不会在函数中改变。当你写"dog"时,字符数组中的数据看起来像这样:

{'d','o','g','\0'}

请注意,它以NUL终止。
您正在使用的函数:

char *strncpy(char *dest, const char *src, size_t n)

src复制到dst,最大长度为n,您无法复制到"cat"。如上所述,您可以看到char *dest不是常量,但const char * src是常量。因此源可能是"cat""dog"
如果要为字符串分配空间,则允许修改它:

char cat_str[] = "cat";

现在字符数组cat_str被初始化为"cat",但是我们可以随时更改它,注意它的长度将是4(每个字母一个,加上一个NUL),因为我们没有指定长度。所以请确保不要更改cat_str[3]之后的任何内容,您可以通过0到3对它进行索引

s71maibg

s71maibg4#

一些静态分析工具有一个常见的误解,认为strncpystrcpy的一个更安全的版本。事实并非如此,它有一个不同的目的。如果我们坚持使用它来防止缓冲区溢出,你需要认识到一个事实,即对于它的签名

char * strncpy ( char * destination, const char * source, size_t num );

如果sourcenum长,则destination的末尾不会隐式附加空字符。因此,在这种情况下,destination不应被视为以空结尾的C字符串(这样阅读它会溢出)。
所以如果你知道你的源代码是一个以空结尾的C字符串,那么你可以做以下事情:

#include <stdio.h>
#include <string.h>

int main()
{
  const char* source = "dog";
  char destination[4] = "cat";

  printf("source is %s\n", source);
  printf("destination is %s\n", destination);

  /* the strlen+1 accounts for null termination on source */
  /* but you need to be sure that source can fit into destination */
  /* and still be null terminated - (that's on you the programmer) */
  strncpy(destination, source, strlen(source) + 1);

  printf("source is still %s\n", source);
  printf("destination is now %s\n", destination);

  return 0;
}

相关问题