我的字符串在 strcpy() 和自定义函数中发生了什么变化?

What happened to my strings in both strcpy() and custom function?

我最近做的字符串函数做得很好。然后,我制作了我的第三个字符串函数,基本上类似于 strcpy():

#include <stdio.h>
#include <string.h>

const char *copy_str(const char *str);

int main() {
    char name[256];
    printf("What's your name? "); scanf("%255s", name);
    char result[256] = copy_str(name);
    printf("Hello, %s.\n", result);
}

const char *copy_str(const char *str) {
    return str;
}

我没有尝试在我制作的函数中使用strcpy()函数本身,因为我不是很熟悉它。然后我得到一个错误:

copy_str.c:9:10: error: array initializer must be an initializer list or string literal
    char result[256] = copy_str(name);
         ^

我是这样修复的:

int main() {
    char name[256];
    printf("What's your name? "); scanf("%255s", name);
    char result[256];
    strcpy(name, result);
    printf("Hello, %s.\n", result);
}

但随后的输出是这样的:

What's your name? builderman
Hello, .

由于某种原因没有字符串。即使您输入不同的字符串,结果也是一样的。

问:为什么 strcpy() 毁了我的字符串?我可以通过哪些方式改进我的功能?

我会尽量分部分回答你的问题。

  1. copy_str.c:9:10: 错误:数组初始值设定项必须是初始值设定项列表或字符串文字

    char 结果[256] = copy_str(名称);

这个错误的意思是在 C 语法中你不能像你那样初始化一个数组。 你只能用这样的文字初始化一个字符数组:

char name[] = "Hello";

或像这样的初始化列表:

char name[] = {'H', 'e', 'l', 'l', 'o'};

您不能使用指向 char 的指针初始化数组(这是您函数的 return 值)

  1. strcpy 不会神奇地将整个字符串复制到另一个字符串,它会遍历字符串直到找到 NULL 终止符 '\0' 所以 strcpy 的简单实现可以是:

    char *StrCpy(char *dest, const char *src)
    {
     char *returned_str = dest;
    
     while (*src != '[=12=]')
     {
        *dest = *src;
        src++;
        dest++;
     }
     *dest = '[=12=]';
    
     return returned_str;
    }
    

因此 strcpy 遍历字符串并将每个字符从 dest 复制到 src。 发送数组末尾没有空终止符的字符数组时可能会出现问题,这就是字符串在 C 中的终止方式。

函数strcpy有如下声明

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

即第一个参数定义了复制第二个参数指向的字符串的数组

但是在你的程序中

int main() {
    char name[256];
    printf("What's your name? "); scanf("%255s", name);
    char result[256];
    strcpy(name, result);
    printf("Hello, %s.\n", result);
}

您正在将 non-initialized 字符数组 result 复制到数组 name

你必须写

    strcpy( result, name );

而不是

    strcpy(name, result);

至于第一个程序那么函数copy_str是多余的。你可以只写

char result[256] = name;

然而,由于数组隐式转换为指向其第一个元素的指针,因此初始值设定项的类型为 char *。所以这样的数组初始化是不正确的。您可以使用

这样的字符串文字来初始化字符数组
char s[] = "Hello";

但是你不能像

那样使用字符指针来初始化字符数组
char t[] = "Hello";
char s[] = t;

您的函数 copy_str 可能如下所示

char * copy_str( char *dsn, const char *src )
{
    for ( char *p = dsn; ( *p++ = *src++ ); );

    return dsn;
}