0
#include<stdio.h>

char* my_strcpy(char*,const char*);

int main(){
        char a[20];
        char* s = "Hello world!";
        char* d = a;
        my_strcpy(d,s);
        printf("\n d : %s \n",d);
        return 0;
}

char* my_strcpy(char* dest,const char* sour){
        if(NULL == dest || NULL == sour){
                return NULL;
        }
        while(1){
                *dest++ = *sour++;
                if(*sour == '\0'){
                        *dest = *sour;
                        break;
                }
        }
}

为什么我们需要 char* 作为 my_strcpy 的返回类型。如果 d 是“”,它会给我一个分段错误。如果我将它分配给它,它工作正常。为什么给定“”时会出现段错误。

修改:在答案之后

#include<stdio.h>

char* my_strcpy(char*,const char*);

int main(){
        char* ret;
        char a[20];
        char* s = "Hello world!";
        char* d = "";
        ret = my_strcpy(d,s);
        if(NULL == ret){
                perror("\nret");
        }
//      printf("\n d : %s \n",d);
        return 0;
}

char* my_strcpy(char* dest,const char* sour){
        char* temp;

        if(NULL == dest || NULL == sour){
                return NULL; 
        }

        temp = dest;
        while(1){ 
                *temp++ = *sour++;
                if(*sour == '\0'){
                        *temp = *sour;
                        break;
                }
        }
        return temp;
}

这仍然给出了段错误。如果 s="" 传递给函数 strcpy 时如何处理条件。

4

5 回答 5

3

你问:“如果 d 是”“它会给我一个分段错误。” 答:如果你给d赋值“”或“”,将没有足够的空间来容纳“Hello World”。此外,如果将常量字符串分配给标记为数据的内存页面,则可能不允许修改。

您问“为什么我们需要 char* 作为 my_strcpy 的返回类型”作为我假设的原始 strcpy。答:您不必这样做。您可以将 void 作为返回类型。但是,如果要执行以下操作,它会变得实用:

printf ("%s", strcpy (dest, sour));

更正的代码:

    while(1){
            *dest++ = *sour++;
            if(*(sour-1) == '\0'){
                    break;
            }

或更好:

            while(*sour != '\0'){
                *dest++ = *sour++;
            }
           *dest = *sour;
于 2013-10-04T05:37:48.933 回答
2

你在这里:

  1. 将 *sour 处的值分配给 *dest
  2. 增加酸和目标,所以现在指向下一个字符
  3. 测试 *dest 现在是否为 NUL 以退出循环

如您所见,第三步从未初始化的内存中读取。您应该测试在递增之前分配的值是否为 NUL。

            *dest++ = *sour++;
            if(*dest == '\0'){
                    break;
            }

如果你传入的 dest 是一个像 " " 这样的常量字符串,你会得到一个段错误,因为字符串常量存储在只读内存中。它们不能被修改。

于 2013-10-04T05:33:26.047 回答
2

正确的:

 if(*dest == '\0'){

应该:

 if(*(dest - 1) == '\0'){

笔记:

 *dest++ = *sour++;

相当于

*dest = *sour;
sour++;
dest++;

您在分配后递增dest,因此您正在检查\0存在垃圾值的位置,因为您没有初始化a[]- 导致未定义的行为。此外,您不会在 while 循环后返回。

您可以简单地将函数编写为:

char* my_strcpy(char* dest,const char* sour){
     if(NULL == dest || NULL == sour)
         return NULL;
    char* d = dest;
     while(*dest++ = *sour++)
        ;
     return d;
}

试试看!!

于 2013-10-04T05:27:30.400 回答
0

这是一个简单的版本:

char *my_strcpy(char *d, const char *s){
  int i=0;
  while(d[i++]=*s++)
    /*done inside condition*/;
  return d;
}
于 2013-10-04T06:32:59.743 回答
0

我建议将 strcpy 实现为:

char* my_strcpy (char* s1, const char* s2)
{
  char* return_val = s1;

  *s1 = *s2;

  while(*s2 != '\0')
  {
    s1++;
    s2++;
    *s1 = *s2;
  }

  return return_val;
}

始终避免在同一个表达式中使用多个 ++ 语句。没有理由这样做,它迟早会给你一些未定义/未指定的行为错误。

于 2013-10-04T06:35:43.857 回答