【问题标题】:C++: strcpy Function copies null?C ++:strcpy函数复制null?
【发布时间】:2012-08-06 15:10:38
【问题描述】:

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

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

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

然后我这样做了:

cout&lt;&lt;s1+4 &lt;&lt; endl;

它打印出“opo”;

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

所以在考虑了一下之后。

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

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

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

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

【问题讨论】:

  • 对我来说很合适。你的测试似乎证明了这一点。虽然调试器会向您显示 char 数组的每个字节中的内容。
  • strcpy() 函数将 src 指向的字符串,包括终止的空字节 ('\0') 复制到 dest 指向的缓冲区中。字符串不能重叠,并且目标字符串 dest 必须足够大以接收副本。 linux.die.net/man/3/strcpy

标签: c++ string null


【解决方案1】:

你的推理是正确的,并且很容易被任何体面的manual证实:

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

【讨论】:

    【解决方案2】:

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

    C11 标准对strcpy 有这样的说法:

    7.24.2.3 strcpy 函数

    简介:

    #include &lt;string.h&gt;
    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++ 中的旧字符串)被定义为一系列字符,直到并包括 first \0 终止符。

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • strncpy 也会复制空终止符,如果有空间的话。为了达到预期的效果,您需要类似memcpy(s1, s2, strlen(s2))
      • strncpy(s1,s2,strlen(s2)) 也不应该复制 0 终止符。
      【解决方案4】:

      这是正确的。

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

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

          来自strcpy 的手册页:

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

          【讨论】:

            【解决方案7】:

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

            cout

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-02-23
              • 2021-11-11
              • 2011-09-03
              • 2015-06-24
              • 2015-01-27
              • 2021-08-12
              • 2013-10-18
              相关资源
              最近更新 更多