28

在专门使用字符串操作函数strcpy时,我做了这个小程序。

char s1[8]="Hellopo";
char s2[4]="sup";
strcpy(s1,s2);
cout<<s1<<endl;

当我打印出 s1 它实际上只是打印出“sup”。我希望它打印“suplopo”。

然后我这样做了:

cout<<s1+4 << endl;

它打印出“opo”;

而这个的输出:cout<<s1+3<<endl; 什么都没有

所以在考虑了一下之后。

我得出了这个结论。由于 C++ 一旦到达空终止符就停止输出字符串。因此 null 必须已复制到strcpy函数中。导致这个字符串:

s - u - p - \0 - o - p - o -\0;

请告诉我这是否正确。如果我不是,请纠正我。

如果您有更多信息要提供,请提供。

4

7 回答 7

46

您的推理是正确的,并且很容易被任何体面的手册确认:

strcpy()函数将 指向的字符串src,包括终止的空字节 ( '\0') 复制到 指向的缓冲区dest

于 2012-08-06T15:13:58.450 回答
5

您关于复制终止字符的推理是正确的。C++ 标准(这是该语言的最终规范)在这方面遵循 C(例如,C++14 遵循 C99,C++17 遵循 C11)。

C11 标准有这样的说法strcpy

7.24.2.3strcpy功能

概要:

#include <string.h>
char *strcpy(char * restrict s1, const char * restrict s2);

描述:

strcpy函数将 所指向的字符串s2(包括终止空字符)复制到 所指向的数组中s1。如果复制发生在重叠的对象之间,则行为未定义。

回报:

strcpy函数返回 的值s1

如果您只想替换字符串的前三个字符,可以使用memcpy()复制特定数量的字节:

memcpy(s1, s2, strlen(s2));

请记住,这只会复制这些字节,仅此而已。如果s1还不是至少长度为 的字符串s2,那么它不太可能很好地结束 :-)


请记住一件事,即您的评论“...导致此字符串:sup\0opo\0”。

不是字符串。C 中的字符串(以及 C++ 中的旧字符串)被定义为一系列字符,直到并包括第一个 \0终止符。

您可能有一系列字符直到原始字符(现在是第二个字符)\0,但字符串实际上比这更短。这可能看起来有点迂腐,但理解定义很重要。

于 2018-02-01T02:08:32.743 回答
2

你是对的。对于您最初预期的效果,您将使用strncopy. strncopy只要您指定要复制的字符串的正确长度,就会复制空终止符。

于 2012-08-06T15:15:29.313 回答
1

这是对的。

http://pubs.opengroup.org/onlinepubs/009695399/functions/strcpy.html

strcpy() 函数应将 s2 指向的字符串 (包括终止的空字节)复制到 s1 指向的数组中。

于 2012-08-06T15:15:35.160 回答
1

是的,这是正确的。strcpy 将包含空终止符。重要的是,如果您将字符串复制到一个新的内存块,您希望它默认为空终止。我相信 strncpy 可能是你在这种情况下所追求的。

我也知道它只是测试代码,但在这个时代我会小心在字符串中使用 +X 偏移量...... ascii 通常会在我们现在生活的 utf8/unicode 世界的后端咬人。

于 2012-08-06T15:17:41.387 回答
1

从手册页strcpy

strcpy()函数将 指向的字符串src,包括终止的空字节 ( '\0') 复制到 指向的缓冲区dest。字符串不能重叠,并且目标字符串 dest必须足够大以接收副本。

于 2012-08-06T15:15:07.533 回答
0

是的,您的推理是正确的,如果您将第 4 个字符 's1[3]' 显式类型转换为整数,如下所示:

cout<<(int)s1[3];

您会得到“0”作为输出,它是 NULL 字符的 ASCII 值。

于 2019-07-08T10:51:04.197 回答