【问题标题】:<ask> modified string using memcpy<ask> 使用 memcpy 修改字符串
【发布时间】:2022-01-24 01:23:47
【问题描述】:

谁能解释我的代码有什么问题

#include <iostream>
#include <cstring>
#include <string.h>
    
using namespace std;
    
int main () {
    
    char x[] = "abcdefghi123456";  // length 15
    
    cout << "original string length: " << strlen(x) << endl;
    cout << "string before modified: " << x << endl;
    
    while ((strlen(x) % 4) != 0)
    
    {
        memcpy(x+strlen(x),"n",1);
    }
        
    cout << "string length after modified: " << strlen(x) << endl;
    cout << "string after modified: " << x << endl;
    
    return 0;
}

上面代码的结果是:

【问题讨论】:

  • 一方面,没有代码,因为都是cmets
  • 我还要指出,超出数组范围是未定义的行为;那时你不能指望任何事情。
  • 是的。我可以解释。您使用的是 char[] 而不是 std::string。 char 数组的大小固定为 15,并且不会增长。如果你尝试用 memcpy 附加一些东西,你会越界。在 C++ 中不要对字符串使用 char 数组
  • 这段代码应该做什么?不管是什么,它很可能不需要你以这种方式编写代码,即使用memcpy,重复调用strlen,等等。

标签: c++


【解决方案1】:

首先,&lt;cstring&gt;&lt;string.h&gt; 是同一个东西,只是&lt;cstring&gt;&lt;string.h&gt; 的内容包装到std 命名空间中。无需同时使用两个标题,使用其中一个 - 在 C 中使用 &lt;string.h&gt;,在 C++ 中使用 &lt;cstring&gt;

更重要的是,x 是一个由 16 个chars 组成的固定大小的数组,因为它使用包含 15 个字母数字 + 一个空终止符的字符串字面量进行初始化。这与您执行以下操作相同:

//char x[] = "abcdefghi123456";
char x[] = {'a','b','c','d','e','f','g','h','i','1','2','3','4','5','6','\0'};

因此,初始 strlen(x) 返回 15(因为不计算空终止符)。 15 % 4 不为 0,因此进入了 while 循环,在第一次迭代中,x+strlen(x) 指向数组的 '\0' 空终止符:

{'a','b','c','d','e','f','g','h','i','1','2','3','4','5','6','\0'}
  ^                                                           ^
  |                                                           |
  x                                                         x + 15

然后memcpy()'n' 覆盖:

{'a','b','c','d','e','f','g','h','i','1','2','3','4','5','6','n'};
                                                              ^

从那时起,x 不再以空值结尾,因此strlen(x) 的任何进一步使用将导致未定义的行为,因为它超出了数组的边界进入周围的内存.

对于您要执行的操作,请改用std::string

#include <iostream>
#include <string>
    
using namespace std;
    
int main () {
    
    string x = "abcdefghi123456";  // length 15
    
    cout << "original string length: " << x.size() << endl;
    cout << "string before modified: " << x << endl;
    
    while ((x.size() % 4) != 0)
    {
        x += 'n';
    }
        
    /* alternatively:
    x.resize((x.size() + 3) & ~3, 'n');
    */

    cout << "string length after modified: " << x.size() << endl;
    cout << "string after modified: " << x << endl;
    
    return 0;
}

【讨论】:

  • 谢谢,问题解决了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 2017-09-26
  • 2014-05-30
  • 2018-04-10
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多