【问题标题】:assigning first variable of struct to another将结构的第一个变量分配给另一个
【发布时间】:2021-04-04 11:48:17
【问题描述】:

我有 struct point 它有两个变量,我不知道如何将字符串从一个变量分配给另一个变量。对指针还不熟悉,不知道该不该用。

struct point
{
    int a, b;
    char name[5];
} A = {3, 5, "plane"}, B;

int main(){
    struct point B = {A.a, A.b, A.name};
    printf("%d %d %s", B.a, B.b, B.name);
}

输出为:3 5 ♀。如何将 A 的字符串分配给 B?

【问题讨论】:

    标签: arrays c struct char initialization


    【解决方案1】:

    问题是一个包含 5 个字符的数组与一个字符串 "plane" 的比值是一比一。您需要一个包含 6 个字符的数组(一个用于空终止符)。如果没有那个空终止符,当变量作为参数提供给%s 转换说明符时,将发生越界访问(搜索空终止符),这将导致undefined behaviour

    改变

    char name[5];
    

    char name[6];
    

    如果您打算将name 用作字符串

    也就是说,要将一个结构变量的值复制到另一个相同类型的变量中,只需要使用赋值运算符=,比如

     struct point B = A;
    

    【讨论】:

    • 警告:从 'char *' 初始化 'char' 从指针中生成整数,而无需强制转换 [-Wint-conversion] 17 |结构点 B = {A.a, A.b, A.name}; | ^ 对,我忘了\0,但还是有错误。
    • @qu4lizz 那是因为分配给数组类型。我更新了答案。
    【解决方案2】:

    要在 C 中声明一个字符串,您必须考虑最后一个元素始终是 \0(它是 NULL ascii 字符)以便包含“平面”,您的数组应该是“平面”的大长度 + 1(6,{'p','l','a','n','e','\0'})。


    如果你想使用指针:

    只需将B 声明为结构指针(*B),然后将其指向A,以便打印A 的值,您只需将B 指向它们即可。

    #include <stdio.h>
    
    struct point
    {
        int a, b;
        char name[6];
    } A = {3, 5, "plane"}, *B;
    
    int main(){
        //struct point B = {A.a, A.b, A.name};
        B = &A;
        printf("%d %d %s", B->a, B->b, B->name);
    }
    

    没有指针:

    您只需将struct point B = {A.a, A.b, A.name}; 替换为B = A;

    #include <stdio.h>
    
    struct point
    {
        int a, b;
        char name[6];
    } A = {3, 5, "plane"}, B;
    
    int main(){
        //struct point B = {A.a, A.b, A.name};
        B = A;
        printf("%d %d %s", B.a, B.b, B.name);
    }
    

    【讨论】:

    • 嗨,我注意到我的错误并在之前的回复编辑中更正了它,但我不明白为什么它没有出现。无论如何,我为这个错误道歉。
    【解决方案3】:

    我在运行这个程序时收到了这个警告

    main.c:12:34: 警告:初始化从没有强制转换的指针生成整数 [-Wint-conversion]
    main.c:12:34: 注意:('B.name[0]' 的初始化接近)

    您不能将地址分配给数组,将name 声明为指针或使用strcpy,如下所示。

    另外你的数组name 应该有一个\0 的空间,所以将它声明为char name[6];

    int main(){
        struct point B =  {A.a, A.b};//, A.name};
        
        strcpy(B.name,A.name);
        
        printf("%d %d %s", B.a, B.b, B.name);
    }
    

    【讨论】:

    • 根据编译器,这是警告而不是错误。
    • @KrishnaKanthYenumula,你当然是对的,这是一个会影响输出的警告,我会更正措辞。
    【解决方案4】:

    你的代码的问题是在这个声明中

    struct point B = {A.a, A.b, A.name};
    

    最后一个初始化器A.name 具有指针类型char *,用于初始化字符数组。不能用指针初始化数组。

    你可以写

    struct point B = A;
    

    考虑到由于这个初始化

    struct point
    {
        int a, b;
        char name[5];
    } A = {3, 5, "plane"}, B;
    

    字符数组A.name 不包含字符串,因为数组中没有空格用于字符串文字的终止零字符'\0'

    因此,您不能在printf 的调用中使用格式字符串%s

    printf("%d %d %s", B.a, B.b, B.name);
    

    你可以写

    printf("%d %d %.*s", B.a, B.b, ( int )sizeof( B.name ), B.name);
    

    那是你的程序可能看起来像

    #include <stdio.h>
    
    struct point
    {
        int a, b;
        char name[5];
    } A = {3, 5, "plane"}, B;
    
    int main( void ){
        struct point B = A;
        printf("%d %d %.*s", B.a, B.b, ( int )sizeof( B.name ),B.name);
    }
    

    如果您希望字符数组name 包含一个字符串,那么您需要将其大小至少扩大一个字符,例如

    struct point
    {
        int a, b;
        char name[6];
    } A = {3, 5, "plane"}, B;
    

    在这种情况下,您可以使用printf的以下调用

    printf("%d %d %s", B.a, B.b, B.name);
    

    【讨论】:

      猜你喜欢
      • 2018-03-29
      • 1970-01-01
      • 2011-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多