C++ char数组在上一次迭代中复制整个单词而不是单个字母 #包括 使用名称空间std; void myStrcpy(char[],char[]); int main(int argc,const char*argv[]{ 字符c1[]=“htako”; 字符c2[]=“标记”; myStrcpy(c1,c2); 您的代码可能有两个问题: 您正在使用基于c的字符串,但忘记了将终止空字符写入c2 您在c2中没有足够的空间容纳该空字符

C++ char数组在上一次迭代中复制整个单词而不是单个字母 #包括 使用名称空间std; void myStrcpy(char[],char[]); int main(int argc,const char*argv[]{ 字符c1[]=“htako”; 字符c2[]=“标记”; myStrcpy(c1,c2); 您的代码可能有两个问题: 您正在使用基于c的字符串,但忘记了将终止空字符写入c2 您在c2中没有足够的空间容纳该空字符,c++,C++,要解决第一个问题,请在while循环之后添加c2[i]=0; 要修复第二个问题,请使用char c2[6]=“Mark”; 请注意,这里需要6来保存来自“htako”+终止空字符的5个字符 更详细地说:charc1[]=“htako”实际上定义了长度为6的字符数组: {'h','t','a','k','o',\0} char c2[]=“Mark”定义长度为5的较短字符数组: {'M','a','r','k',\0} 因此,当您的while循环在处理c1到c2之后结束时,您将在c2的位置处: {

要解决第一个问题,请在while循环之后添加
c2[i]=0;

要修复第二个问题,请使用
char c2[6]=“Mark”;
请注意,这里需要6来保存来自“htako”+终止空字符的5个字符

更详细地说:
charc1[]=“htako”
实际上定义了长度为6的字符数组:

{'h','t','a','k','o',\0}

char c2[]=“Mark”
定义长度为5的较短字符数组:

{'M','a','r','k',\0}

因此,当您的while循环在处理c1到c2之后结束时,您将在c2的位置处:

{'h','t','a','k','o'}

请注意,您没有终止空字符。此外,cince c2隐式声明长度为5,您没有空间添加它。因此,当您将修改后的c2输出到cout时,因为您使用的是字符[]实际上,CUT实际上没有接收到长度为 char */COD>的长度,并且通过C-String约定,通过搜索终止的空字符来确定字符串的长度。因为没有该空字符,CUT将经过<代码> C2 < /代码>的结尾,搜索它并访问有效的AES之外的数据是C++程序的未定义行为。您的特定计算机堆栈不断增长,因此c1恰好位于c2之后,您会看到“htakohtako”打印出来。但实际上,您的程序也可能会因SEGV而失败或执行任何数量的不愉快操作。这种类型的错误称为缓冲区溢出,是许多安全漏洞的根源。请不惜一切代价避免这种错误



但实际上,
std::string
在这里是更合适、更安全的选择,除非您只是在玩弄C字符串如何在内部工作。

您的代码有两个问题:

  • 您正在使用基于c的字符串,但忘记了将终止空字符写入
    c2
  • 您在
    c2
    中没有足够的空间容纳该空字符
要解决第一个问题,请在while循环之后添加
c2[i]=0;

要修复第二个问题,请使用
char c2[6]=“Mark”;
请注意,这里需要6来保存来自“htako”+终止空字符的5个字符

更详细地说:
charc1[]=“htako”
实际上定义了长度为6的字符数组:

{'h','t','a','k','o',\0}

char c2[]=“Mark”
定义长度为5的较短字符数组:

{'M','a','r','k',\0}

因此,当您的while循环在处理c1到c2之后结束时,您将在c2的位置处:

{'h','t','a','k','o'}

请注意,您没有终止空字符。此外,cince c2隐式声明长度为5,您没有空间添加它。因此,当您将修改后的c2输出到cout时,因为您使用的是字符[]实际上,CUT实际上没有接收到长度为 char */COD>的长度,并且通过C-String约定,通过搜索终止的空字符来确定字符串的长度。因为没有该空字符,CUT将经过<代码> C2 < /代码>的结尾,搜索它并访问有效的AES之外的数据是C++程序的未定义行为。您的特定计算机堆栈不断增长,因此c1恰好位于c2之后,您会看到“htakohtako”打印出来。但实际上,您的程序也可能会因SEGV而失败或执行任何数量的不愉快操作。这种类型的错误称为缓冲区溢出,是许多安全漏洞的根源。请不惜一切代价避免这种错误



但实际上,
std::string
在这里更合适、更安全,除非您只是在玩弄C字符串如何在内部工作。

您的问题的答案与内存的布局有关。如果您检查内存,您会看到:

#include <iostream>
using namespace std;
void myStrcpy(char [], char []);  
int main(int argc, const char * argv[]) {
    char c1[] = "htako";
    char c2[] = "Mark";

    myStrcpy(c1, c2);
    cout << c2 << endl;

    return 0;
}

void myStrcpy (char c1[], char c2[]) {
    int i = 0;
    while(c1[i] != '\0') {
        c2[i] = c1[i];
        cout << c1[i] << "  ::: " << i << endl;
        i++;
    }
}
代码中有两个问题

  • 您的缓冲区溢出
    c2
    只有5个字节(标记+空终止符),但您正在覆盖空终止符,因为
    c1
    有6个字节长(htako+空终止符)
  • 终止字符串时不能为null

  • 您看到字符串似乎在增长,因为您覆盖了空终止符。在其他情况下,您的程序可能会崩溃。

    问题的答案与内存的布局有关。如果检查内存,您将看到:

    #include <iostream>
    using namespace std;
    void myStrcpy(char [], char []);  
    int main(int argc, const char * argv[]) {
        char c1[] = "htako";
        char c2[] = "Mark";
    
        myStrcpy(c1, c2);
        cout << c2 << endl;
    
        return 0;
    }
    
    void myStrcpy (char c1[], char c2[]) {
        int i = 0;
        while(c1[i] != '\0') {
            c2[i] = c1[i];
            cout << c1[i] << "  ::: " << i << endl;
            i++;
        }
    }
    
    代码中有两个问题

  • 您的缓冲区溢出
    c2
    只有5个字节(标记+空终止符),但您正在覆盖空终止符,因为
    c1
    有6个字节长(htako+空终止符)
  • 终止字符串时不能为null

  • 您看到字符串似乎在增长,因为您覆盖了空终止符。在其他情况下,您的程序可能会崩溃。

    为什么要传递
    char[] >不是<代码> char */COD>?更重要的是,为什么你在C++中编写自己的<代码> StrcPy <代码>,其中代码“> STD::String < /Cord>”?因为这是C++,你可以使用<代码> STD::String 。问问自己C1和C2的大小是什么?它们是否相同?你的复制函数也忘记终止在 C2< /C>中的字符串。让魔鬼来鼓吹:练习的目的要么是你自己找到解决方案,要么你最好使用
    std::string
    std::copy
    ,但在这里询问如何修复它不会让你了解如何滚动自己的字符串为什么要传递
    char[]
    而不是
    char*
    ?更重要的是,为什么要编写自己的