C语言 - 复制两种不同的结构类型

时间:2017-06-26 14:36:44

标签: c struct copy

有没有办法复制具有相似内容的两种不同结构类型,而无需按变量复制变量?

例如,读取文件,保存到pessoa并复制到xpessoa,假设email'not defined'

struct pessoa {
    char nome[50];
    char telefone[20];
    struct{
    int dia,mes,ano;
    }data_nasc;
};

struct xpessoa {
    char nome[50];
    char telefone[20];
    struct{
    int dia,mes,ano;
    }data_nasc;
    char email[50];
};

3 个答案:

答案 0 :(得分:6)

保证可行的方法是将pessoa嵌入xpessoa,如下所示:

struct xpessoa {
    pessoa p;
    char email[50];
};

如果pessoa布局发生更改,此方法可以保护您的代码免受未定义的行为影响,因为xpessoa不再镜像其布局。

答案 1 :(得分:1)

如果由于某种原因你不允许改变任何一种结构,你可以这样做:

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

struct pessoa {
    char nome[50];
    char telefone[20];
    struct{
    int dia,mes,ano;
    }data_nasc;
};

struct xpessoa {
    char nome[50];
    char telefone[20];
    struct{
    int dia,mes,ano;
    }data_nasc;
    char email[50];
};

int main() {
  struct pessoa p = {"John", "111-222", {1, 2, 3}};
  struct xpessoa xp = { .email = "john@org.org"};
  memcpy(&xp, &p, sizeof(p));
  printf("name: %s email: %s \n", xp.nome, xp.email);
  return 0;
}

然而,正如@dasblinkenlight所说,这将是一种非常危险的方法,因为它需要手动跟踪这两种结构。

答案 2 :(得分:0)

如果你不能改变“扩展”结构以包含“基础”结构作为其初始成员,将整个“基础”结构复制到“扩展”结构的唯一合法方法是定义包含两个结构的联合作为成员的类型。

引用C11第6.5.2.3节(结构和工会成员)第6段:

  

为了简化联合的使用,我们做了一个特别的保证:如果一个联合包含几个共享一个共同初始序列的结构(见下文),并且如果联合对象当前包含这些结构中的一个,则允许检查其中任何一个的共同初始部分,可以看到完整类型的联合声明。如果对应的成员具有一个或多个初始成员的序列的兼容类型(并且对于位字段,具有相同的宽度),则两个结构共享公共初始序列

因此,您可以定义包含struct pessoastruct xpessoa类型成员的联合,并从任一成员访问公共部分:

union upessoa {
    struct pessoa p;
    struct xpessoa xp;
};

int somefunc(void) {
    union upessoa a = { .p = {"Fred", "555-5555", {1, 2, 3} };
    // This is legal because data_nasc is part of the common initial sequence
    return a.xp.data_nasc.ano;
}

根据我的经验,许多代码忽略了结构成为联合成员的这一要求,并假设如果任何两个结构共享一个共同的初始序列,则可以在不同结构的对象之间复制公共初始序列类型;但这会导致未定义的行为 - 它可能会起作用,但它不可移植。