使用字符指针模拟c中的strcpy函数

使用字符指针模拟c中的strcpy函数,c,pointers,C,Pointers,我正在尝试编写一个用户定义的函数,它将完全执行strcpy()library函数的功能。但尽管并没有错误,我的程序崩溃了,并没有将第二个字符串复制到第一个字符串。此代码有什么问题,如何修复 #include<stdio.h> #include<string.h> int main(){ char *ch1="abcd"; char *ch2="efgh"; str_cpy(ch1,ch2); } str_cpy(char *c1,char *

我正在尝试编写一个用户定义的函数,它将完全执行
strcpy()
library函数的功能。但尽管并没有错误,我的程序崩溃了,并没有将第二个字符串复制到第一个字符串。此代码有什么问题,如何修复

#include<stdio.h>
#include<string.h>
int main(){

    char *ch1="abcd";
    char *ch2="efgh";
    str_cpy(ch1,ch2);

}

str_cpy(char *c1,char *c2){

    int i=0;


    while(c1[i]!='\0'){

          i++;
    }
    printf("%c",*(c1+3));
    int k;
    for(k=0;k<=i;k++){

          *(c1+k)=*(c2+k);
    }

}
#包括
#包括
int main(){
char*ch1=“abcd”;
char*ch2=“efgh”;
str_-cpy(ch1,ch2);
}
str_cpy(char*c1,char*c2){
int i=0;
而(c1[i]!='\0'){
i++;
}
printf(“%c”,*(c1+3));
int k;

对于(k=0;k字符串文本通常放在只读区域,这就是为什么在写入
c1
时程序崩溃的原因。目标字符串需要是数组或分配的缓冲区:

char c1[5];
str_cpy(c1, c2);
此外,在函数中,看起来您正在将
c2
复制到
c1
,但是您正在计算
c1
的长度,您应该计算
c2
的长度:

// copy string c2 to c1
void str_cpy(char *c1, const char *c2){

    int i=0;
    while(c2[i]!='\0'){
      i++;
    }

    int k;
    for(k=0;k<=i;k++){
        *(c1+k)=*(c2+k);
    }
}
//将字符串c2复制到c1
void str_cpy(字符*c1,常量字符*c2){
int i=0;
而(c2[i]!='\0'){
i++;
}
int k;

对于(k=0;k您的程序调用未定义的行为,因为您正试图写入字符串文字。字符串文字可能存储在只读内存中,这在您的系统上可能是如此,因此会导致崩溃

请注意,字符串复制函数可以在单个循环中执行复制:

char *str_cpy(char *c1, const char *c2) {
    for (int i = 0;; i++) {
        c1[i] = c2[i];
        if (c1[i] == '\0')
            return c1;
    }
}
您可以使用修改的
main
验证行为:

#include <stdio.h>

char *str_cpy(char *c1, const char *c2) {
    for (int i = 0;; i++) {
        c1[i] = c2[i];
        if (c1[i] == '\0')
            return c1;
    }
}

int main(void) {
    char buf[20];
    char *ch2 = "Hello world\n";
    printf("%s\n", str_cpy(buf, ch2));
    return 0;
}
#include <stdio.h>
#include <stdlib.h>

char *str_cpy(char **c1, const char *c2) {
    int i, size = 0;
    for(i = 0; ; i++)
        if(c2[i] == '\0')break;
    size = i + 1;

    if(!(*c1 = realloc(*c1,size*sizeof(char))))
        return *c1;//or devise some more sophisticated error handling
    for (i = 0;; i++) {
        (*c1)[i] = c2[i];
        if (c2[i] == '\0')
            return *c1;
    }
}

int main(void){
    char *ch1 = malloc(1); //you're responsible for freeing it, once used 
    char *ch2 = "Hello, everybody in the neighborhood!";    
    printf("%s\n",str_cpy(&ch1,ch2));
    free(ch1);
    return 0;
}
#包括
char*str_cpy(char*c1,const char*c2){
对于(int i=0;i++){
c1[i]=c2[i];
如果(c1[i]='\0')
返回c1;
}
}
内部主(空){
char-buf[20];
char*ch2=“Hello world\n”;
printf(“%s\n”,str_cpy(buf,ch2));
返回0;
}

这里有一个可能的代码返工,它不需要预先定义缓冲区大小(c1)。您只需传递缓冲区地址。另外,请注意,一旦使用,此类缓冲区必须释放(例如,如果在本地范围中声明,而不是在
main()
):

#包括
#包括
字符*str_cpy(字符**c1,常量字符*c2){
int i,大小=0;
对于(i=0;i++)
如果(c2[i]='\0')中断;
尺寸=i+1;
如果(!(*c1=realloc(*c1,大小*sizeof(char)))
return*c1;//或者设计一些更复杂的错误处理
对于(i=0;i++){
(*c1[i]=c2[i];
如果(c2[i]=='\0')
返回*c1;
}
}
内部主(空){
char*ch1=malloc(1);//一旦使用,您有责任释放它
char*ch2=“大家好,邻居都好!”;
printf(“%s\n”,str_cpy(&ch1,ch2));
免费(ch1);
返回0;
}

还请注意,您不需要
#包括

目标
ch1
是只读的,因为它是一个不可修改的字符串文本。初始化它也没有意义,因为它将被覆盖。您需要
char ch1[5]
here.comments掠过我的头..简化版请删除第二条注释,这只是一个建议。
char*c1=“stuff”
定义了指向不可变字符串文字的指针。
char c2[5]
为最多四个字符加上空终止符定义了一个可写缓冲区。如果您想用C编程,您必须了解这一点;没有简化版本。@AL-zami我的解决方案是最简单的。const char是什么?@AL-zami它是对函数进行注释,使源字符串
c2
在函数中不会更改在上,只有
c1
将被更改。它可以在没有缺点的情况下工作。它真的有必要吗?如果我不使用const关键字,它可能会产生什么问题?@AL-zami它可以帮助API的用户了解参数的效果和要求,还可以帮助编译器检测潜在的错误,并基于n如果我在ch1='abckABCK'中有一个较大的字符串,在复制后它只是“efgh”,最后四位数字“ABCD”丢失。为什么会发生这种情况?