在不使用内置 strcpy 的情况下实现 strcpy 函数

Implementing strcpy function without using in-built strcpy

我想在不使用内置函数的情况下实现 strcpy 函数。我在网上搜索过,但我只找到了 programs 来完成这个任务,但没有找到 functions.

我尝试了各种方法,但没有成功。最后(尝试 4),我写了一个有效的代码,但我不明白为什么那个东西有效,但以前的方法却不行

只是在寻找一个函数,它可以在从 main() 调用时将一个字符串的值复制到另一个字符串中,并在输出字符串中显示正确的值。如果我能得到它,我将非常感激。当然,我不能使用内置函数,因为我被迫在周一参加考试,我们将不得不实现随机的 7 个字符串函数中的任何一个并解释代码..

编辑:还发现此 https://www.programmersought.com/article/29163684184/ 代码可实现相同的功能,但它是用 C++ 编写的。为什么schools/colleges在C++发明之后还教C?有人知道任何 C++ 到 C 的转换器吗?

尝试 1:

#include <stdio.h>
void strcopy(char *a, char *b)
{
    for (int i = 0; a[i] != '[=10=]'; i++)
    {
        b[i] = a[i];
    }
}
int main()
{
    char a[10];
    printf("Enter string: ");
    scanf("%s", &a);
    printf("Input string: %s", a);
    char b[(sizeof(a))];
    strcopy(a,b);
    printf("\nOutput string: %s", b);

    return 0;
}

输出:

输入字符串:helloworld
输入字符串:helloworld
输出字符串:helloworldhelloworld





尝试 2:

#include <stdio.h>
void strcopy(char *a, char *b)
{
    for (int i = 0; a[i] != '[=11=]'; i++)
    {
        b[i] = a[i];
    }
}
int main()
{
    int n;
    printf("Enter the string size: ");
    scanf("%d",&n);
    char a[n];
    printf("Enter string: ");
    scanf(" %s",&a);
    printf("Input string: %s", a);
    char b[n]; 
    strcopy(a,b);
    printf("\nOutput string: %s", b);

    return 0;
}

输出:

输入字符串大小:7
输入字符串:helloworld
输入字符串:helloworld
输出字符串:helloworldö





尝试 3:

#include <stdio.h>
void strcopy(char *a, char *b)
{
    for (int i = 0; a[i] != '[=12=]'; i++)
    {
        b[i] = a[i];
    }
}
int main()
{
    int n;
    printf("Enter the string size: ");
    scanf("%d",&n);
    n++;
    char a[n];
    printf("Enter string: ");
    // scanf(" %s",&a);
    fgets(a,n,stdin);
    fgets(a,n,stdin);  //need to write twice or it wont work
    printf("Input string: %s", a);
    char b[n]; 
    strcopy(a,b);
    printf("\nOutput string: %s", b);

    return 0;
}

输出:

输入字符串大小:5
输入字符串:helloworld
输入字符串:你好
输出字符串:hello⌂





尝试 4:

#include <stdio.h>
void strcopy(char *a, char *b)
{
    for (int i = 0; a[i] != '[=13=]'; i++)
    {
        b[i] = a[i];
    }
}
int main()
{
    int n;
    printf("Enter the string: ");
    scanf("%d",&n);
    n++;
    char a[n];
    scanf(" %s",&a);
    // printf("Enter string: ");
    // fgets(a,n,stdin);
    // fgets(a,n,stdin);
    printf("Input string: %s", a);
    char b[n]; 
    strcopy(a,b);
    printf("\nOutput string: %s", b);

    return 0;
}

输出:

输入字符串:helloworld
输入字符串:helloworld
输出字符串:helloworld





编辑:

朋友在回答中给出的尝试方法:

代码:

#include <stdio.h>
void strcopy(char *a, char *b)
{
    for (int i = 0; a[i+1] != '[=14=]'; i++)
    {
        b[i] = a[i];
    }
}
int main()
{
    // int n;
    printf("Enter the string: ");
    // scanf("%d",&n);
    // n++;
    char a[10];
    scanf("%s",&a);
    // printf("Enter string: ");
    // fgets(a,n,stdin);
    // fgets(a,n,stdin);
    printf("Input string: %s", a);
    char b[sizeof(a)]; 
    strcopy(a,b);
    printf("\nOutput string: %s", b);

    return 0;
}

输出:

输入字符串:helloworld
输入字符串:helloworld
输出字符串:helloworl





编辑 2:

尝试 do-while 循环:

代码:

#include <stdio.h>
void strcopy(char *a, char *b)
{
    // for (int i = 0; a[i+1] != '[=15=]'; i++)
    // {
    //     b[i] = a[i];
    // }
    int i=0;
    do{
        b[i]=a[i];
        i++;
    }while(a[i] != '[=15=]');
}
int main()
{
    // int n;
    printf("Enter the string: ");
    // scanf("%d",&n);
    // n++;
    char a[10];
    scanf("%s",&a);
    // printf("Enter string: ");
    // fgets(a,n,stdin);
    // fgets(a,n,stdin);
    printf("Input string: %s", a);
    char b[sizeof(a)]; 
    strcopy(a,b);
    printf("\nOutput string: %s", b);

    return 0;
}

输出:

输入字符串:helloworld 输入字符串:helloworld 输出字符串:helloworldhelloworld

您没有添加终止符 [=10=]

您的所有实现都存在相同的基本错误; “尝试 4”只是偶然地起作用。问题出在 strcopy 中的循环终止条件。当您到达结束源字符串的 NUL 字符时,您将停止循环而不是复制它。这意味着目标字符串没有结束并且 printf 越过它的结尾,打印内存中发生的任何内容。您必须改为复制 NUL ,然后 停止循环。

您在为字符串 ab 分配内存时也有错误——在每个实现中都不同,但其中 none 对我来说在抽象上看起来是正确的。与您的导师讨论如何正确执行此操作,这是 C 中最复杂的主题之一,我没有足够的信息来了解您可以使用哪些技术。

在过去 K&R 为王的日子里,我们会在腰带上系一个洋葱,就像当时的风格一样,并做一些类似的事情

void strcopy(char *a, char *b)
{
   while ( *b++ = *a++ ) {}
}

现在我认为旧方法已经过时了

有人建议我解释为什么这样做。

*b = *a做复制一个字节的核心功能

*b++ = *a++ 添加自动增量,在分配完成后将两个指针移动到内存中的下一个位置

while (*b++ = *a++) {} 在复制的字节非零时循环。空 {} 只是为了完成 while 语句

的语法

因此 while 循环将 运行 复制字节,然后将两个指针递增到下一个位置,直到复制的字节为零,成为字符串的结尾

OP 的 strcopy() 在尝试模仿标准库函数时存在各种问题:

char *strcpy(char * restrict s1, const char * restrict s2);

目标数组中缺少 空字符

这是 OP 的主要问题。 不知何故 必须在目标中分配一个空字符。 OP的各种代码都失败了。

提示:考虑复制一个字符串 "",它仅将 分配给 空字符 '[=15=]'目的地。

参数顺序错误

第一个参数应该是要匹配的目的地strcpy()

缺少 return 值

strcpy() returns 原始目标指针。

高级:缺少参数 restrict/const 属性

只需使用上面的库函数签名即可。

高级: 字符串

失败

OP 的代码使用 int 来索引,这对于 long 字符串来说是不够的。最好使用 size_t.

提示:增加输出清晰度

打印结果时,添加前哨字符,如 < > 和最后的 '\n'
对于调试工作,使目标字符串大 2 倍。

// char b[sizeof(a)]; 
char b[sizeof(a) *2]; 
strcopy(a,b);
// printf("\nOutput string: %s", b);
printf("\nOutput string: <%s>\n", b);

OP 断言这不是家庭作业编码任务,因此候选解决方案:

char *strcpy(char * restrict s1, const char * restrict s2) {
  // Use unsigned char as all str functions behave as if char was unsigned
  // Also need to save s1 for return
  unsigned char *us1 = (unsigned char *)s1;
  const unsigned char *us2 = (const unsigned char *)s2;

  while (*us2) {
    *us1++ = *us2++;
  }

  return s1;
}