如何在C中将多个结构数组传递给单个函数

时间:2018-06-20 11:47:07

标签: c arrays file struct binary

我有2个不同的结构数组(用户和来宾),我想知道如何将它们传递给单个函数。例如,我有这些结构

typedef struct {
    int day;
    int month;
    int year;
} date;

typedef struct {
    short id;
    char *name;
    char *surname;
    char *email;
    char *password;
    date birthday;
} user;

typedef struct {
    short id;
    char *name;
    char *surname;
    char *email;
} guest;

,我想使用相同的功能将数据保存在二进制文件中。但是,尽管我试图告诉自己如何将多个结构传递给单个函数,但我在如何将多个结构数组传递给单个函数方面遇到问题。这是到目前为止我想要实现的目标。文件已生成,但不完整。写入过程在两个结构的特定数据处停止。

#include <stdio.h>

#define MAX_USER 20
#define MAX_GUEST 20

user record_user[MAX_USER] = {
{ 1     , "Name 1"          , "Surname 1"           , "name1.surname1@email.com"            , "S\\(6`].}"   ,{ 9    , 3     , 1994 }    ,{ 10   , 3     , 2010 } },
{ 2     , "Name 2"          , "Surname 2"           , "name2.surname2@email.com"            , "O!5[0R9P"    ,{ 29   , 8     , 1977 }    ,{ 18   , 1     , 2009 } },
{ 3     , "Name 3"          , "Surname 3"           , "name3.surname3@email.com"            , "j+$\"XrLw"   ,{ 15   , 9     , 1971 }    ,{ 14   , 3     , 2013 } },
{ 4     , "Name 4"          , "Surname 4"           , "name4.surname4@email.com"            , "\"n^{:&}("   ,{ 15   , 7     , 1980 }    ,{ 11   , 6     , 2011 } },
{ 5     , "Name 5"          , "Surname 5"           , "name5.surname5@email.com"            , "JHKv%Kgg"    ,{ 15   , 4     , 1975 }    ,{ 19   , 8     , 2011 } },
{ 6     , "Name 6"          , "Surname 6"           , "name6.surname6@email.com"            , "o_bsggpN"    ,{ 28   , 5     , 1989 }    ,{ 18   , 9     , 2009 } },
/* it keeps going */
};

guest record_guest[MAX_GUEST] = {
{ 1     , "Name 1"          , "Surname 1"           , "name1.surname1@email.com" },
{ 2     , "Name 2"          , "Surname 2"           , "name2.surname2@email.com" },
{ 3     , "Name 3"          , "Surname 3"           , "name3.surname3@email.com" },
{ 4     , "Name 4"          , "Surname 4"           , "name4.surname4@email.com" },
{ 5     , "Name 5"          , "Surname 5"           , "name5.surname5@email.com" },
{ 6     , "Name 6"          , "Surname 6"           , "name6.surname6@email.com" },
/* it keeps going */
};


    int main() {
        /* some prev code */
        save(record_user, "user.dat", MAX_USER);
        /* some middle code */
        save(record_guest, "guest.dat", MAX_GUEST);
        /* some after code */
        return 0;
    }

    void save(void *data[], char *filename, int size) {
        FILE *file;
        file = fopen(filename, "rb+");

        // If the file is missing, it is created
        if (file == NULL) {
            file = fopen(filename, "wb");
        }

        for (int i = 0; i < size; i++) {
            fwrite(&data[i], sizeof(data[i]), 1, file);
        }

        fclose(file);
    };

2 个答案:

答案 0 :(得分:2)

问题是sizeof(data[i])这是胡说八道,它为您提供了无效的指针大小。

使用现代标准C编程(C11),您可以这样做:

void guest_save (size_t size, guest array[size], const char* filename);

void user_save (size_t size, user array[size], const char* filename);

#define save(size, array, filename) \
  _Generic((array),                 \
           guest*: guest_save,      \
           user*:  user_save)(size, array, filename)

使用此方法,您将不必使用危险的void指针。现在,您可以轻松服用sizeof array[i]等。

答案 1 :(得分:1)

您问题的简短答案:我有2种不同的结构体数组(用户和来宾),我想知道如何将它们传递给单个函数。:将它们组合在一起,同时包括一个unionenum的组合定义...

一些相关的体系结构建议:

  • 首先,消除结构中的指针成员并替换它们 与“足够大”的阵列。 (这将大大简化内存分配和对free()的相应调用。)
  • 2,创建一个单独的组合结构,例如访客,包括所有 其他人。
  • 3,使用enum区分要 创建/存储/使用数据等。
  • 第四,使用联合包含两种类型的访客。

通过这种方式,您可以在函数中传递单个struct参数。

#define MAX_VISITOR 20

typedef struct {
    int day;
    int month;
    int year;
} date;

typedef enum {
    USER,
    GUEST
} TYPE;

typedef struct {
    short id;
    char name[30];  //no pointers here, just create 'large enough' arrays
    char surname[30];  
    char email[30];
    char password[30];
    date birthday;
} user;

typedef struct {
    short id;        
    char name[30];
    char surname[30];
    char email[30];
} guest;

typedef struct {
    date d;       //date
    TYPE t;       //either USER or GUEST
    union   {     //(only one member will be populated per instance of VISITOR)
        user u;   //6 elements
        guest g;  //4 elements 
    };
} VISITOR;

void StoreVisitors(VISITOR *v); //these prototypes will accept a single argument containing single struct. 
void UpdateVisitors(VISITORS **v);

int main(void)
{
    VISITOR *pV = calloc(MAX_VISITOR, sizeof(*pV)); //20 instances of VISITOR
    if(pV)
    {
        UpdateVisitors(&pV);
        StoreVisitors(pV);
    }
    free(pV);


    return 0;
}

void StoreVisitors(VISITOR *p)
{
    // Write the information in p to the data file      
}

void UpdateVisitors(VISITOR **v)
{
    // Read records from existing visitor files
    // and update array of struct VISITOR with data     
}