使用指针的strcpy函数

5

我正在尝试使用指针编写自己的strcpy函数,但在运行时出现错误。

void str_cpy(char **destination, const char *source) {
//    char *s1 = *destination;

   while (*source != '\0') {
      **destination++ = *source++; //Get an error here
   }
   **destination = '\0';
}

我按照以下方式调用函数:
char *str = NULL;
str_cpy(&str, "String");

这个可以吗?

谢谢!


4
为什么你在目标中使用双指针? - squiguy
3
你为什么要把字符串复制到空指针上? - axiom
@axiom:这是一个作业,所以我不能更改main()函数。 - oridahan
7个回答

8
不可以。为什么?因为str是一个空指针,它没有指向任何东西。当您尝试将值写入其中时,它们会去哪里?它没有指向任何分配的内存!您首先需要为str分配内存。您可以执行以下操作:
char *str = malloc(strlen("String") + 1); // + 1 for the '\0' character at the end of C-style strings

或者你可以这样做:

char str[256]; // make str large enough to hold 256 chars. Note that this is not as safe as the above version!

此外,`destination` 应该是一个单指针,而不是双指针。虽然使用双指针并不是技术上的错误,但是这是不必要的。
可选地,您可以在 `str_cpy` 函数中分配内存,像这样:
void str_cpy(char **destination, const char *source) {
    *destination = malloc(strlen(source) + 1);
    // ... continue as normal

问题是这是一项任务,并且我不能更改我的主函数,因此在将str传递给函数之前无法分配内存。 - oridahan
@user1836819:然后在str_cpy中分配内存。我会编辑我的答案来包括这个。 - Cornstalks
谢谢,我做出了更改后就没问题了,但是当我尝试执行之前提到的代码 **destination++ = *source++ 时,它没有正确地递增变量。它递增了地址但没有递增字符串。谢谢! - oridahan

4

为了简单起见,在函数中可以用一行代码来完成此操作。

void mystrcpy(char *dest, const char *src) {
  while (*dest++ = *src++);
}

话虽如此,您确实需要为dest分配内存,可以使用malloc或者简单地使用字符数组char dest[256]


请问您能否解释一下为什么不需要测试终止符\0 - pfabri
好的,请在这里查看答案:https://dev59.com/FFzUa4cB1Zd3GeqP6cZW - pfabri

3
我认为没有必要传递指向指针的指针:
void str_cpy(char *dst, const char *src) {
   while (*src != '\0') {
      *dst++ = *src++; 
   }
   *dst = '\0';
}

在传递之前,您需要为dst分配内存:

const char *src = "String";
char *str = malloc(strlen(src)+1); //plus one for null byte
str_cpy(dst, src);

2

在将指针传递给填充其指向内容的函数之前,您应该为该指针分配一些内存(在此情况下为NULL)。

示例:

char *str = malloc(128);
if (str)
{
   str_cpy(&str, "String");
   free(str);
   str = NULL;
}

我建议不要没有提供目标缓冲区大小信息的情况下执行此操作(即,如果您正在编写自己的代码,则需要检查目标缓冲区的边界,否则您的版本将具有与 strcpy()相同的安全漏洞,这已经足够糟糕了)。
注意:除非您计划更改传递给目标的指针所持有的地址,否则您也不需要使用双指针。您使用的双指针使用方法阻止了传统的 strcpy()用法模式:
char str[128];
str_cpy(&str, "Hello"); // error. 

一个数组地址不能直接作为指向指针的指针传递,因此您的代码无法在没有中间指针的情况下填充静态数组。
char str[128];
char *p = str;
str_cpy(&p, "Hello");  //ok. passing address of pointer.

如果这不是有意为之的(我不知道为什么要这样做,除非你想在空指针通路上内部模拟strdup()),那么你应该解决这个问题。


0
#include<stdio.h>
void main()
{

    void mystrcpy(char *,char *);

    char s1[100],s2[100];
    char *p1;
    char *p2;
    p1=s1;
    p2=s2;
    printf("Enter the string to copy to s2...?\n");
    scanf("%s",p1);


    mystrcpy(p2,p1);

    printf("S2 after copying = %s",p2);

}
void mystrcpy(char *p2,char *p1)
{
    while(*p1!='\0')
    {
        *p2=*p1;
        p2++;
        p1++;
    }
    *p2='\0';

}

这是我的解决方案..易于理解..


0

最近我使用了双指针strcpy实现,遇到了与上面代码相同的问题。

以下代码可能对其他人有所帮助。

 void strcpy_i( char **dst, const char *src )
 {
    *dst=(char *)malloc((strlen(src)+1)*sizeof(char));

    char *tmp=*dst;

    if(tmp == NULL || src == NULL)
    return ;

    while((*tmp++=*src++)!='\0');
}

int main()
{
    char v[]="Vinay Hunachyal";
    char *d=NULL;

    strcpy_i(&d,v);
    printf("%s",d);

 return 0;

}


0

这里是完整的实现。 从这里得到了一篇好文章。描述了时间和性能。虽然我没有自己测量过。 http://www.howstuffworks.com/c35.htm

char* mystrcpy(char *dst, const char *src) {
char *ptr = dst;
while ((*dst++ = *src++) ) ;
return ptr;
}

int main(int argc, char *argv[]) {
const char *src = "This is C.\0";
char *dst = malloc(sizeof(char)*(strlen(src)+1)); //+1 for the null character
dst = mystrcpy(dst, src);
printf("%s",dst);
return 1;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接