C 如何初始化结构

C 如何初始化结构,c,struct,dynamic-arrays,C,Struct,Dynamic Arrays,我不确定这是否是使用值创建和初始化结构的正确方法: #define LINES 4 #define LENGHT 30 typedef struct { char *name; char *phoneNumber; char *location; char *traveltype; } Client; void readClientData(char *filename, char *clientData[]); Client *createClient(char *name

我不确定这是否是使用值创建和初始化结构的正确方法:

#define LINES 4
#define LENGHT 30

typedef struct
{
  char *name;
  char *phoneNumber;
  char *location;
  char *traveltype;
} Client;

void readClientData(char *filename, char *clientData[]);
Client *createClient(char *name, char *phoneNumber, char *location, char *traveltype);

int main(int argc, char *argv[])
{
  char *filename = argv[1];
  char *clientData = (char *)malloc(LINES * sizeof(char)*LENGHT);
  readClientData(filename, &clientData);
  Client *client = createClient(clientData[0], clientData[1], clientData[2], clientData[3]);
  return 0;
}

Client *createClient(char *name, char *phoneNumber, char *location, char *traveltype)
{
  Client *client = malloc(sizeof(Client));
  client->name = strdup(name);
  client->phoneNumber = strdup(phoneNumber);
  client->location = strdup(location);
  client->traveltype = strdup(traveltype);
  return client;
}
我正在尝试创建结构,但出现以下错误:

error: invalid conversion from 'char' to 'char*' [-fpermissive]
   Client *client = createClient(clientData[0], clientData[1], clientData[2], clientData[3]);

error: invalid conversion from 'void*' to 'Client*' [-fpermissive]
   Client *client = malloc(sizeof(Client));

我在这里遗漏了什么?

因为
clientData
是一个
char*
clientData[I]
是一个简单的字符。这与
createClient()
prototype冲突,prototype需要指向以NULL结尾的字符串的指针

请注意,在对它们进行mallock操作之后,您永远不会初始化它们。这在运行时是个问题,因为
strdup()
需要复制某些内容(至少是一个空字符串!)


第二个错误要求您将malloc的结果强制转换为
Client*
(即使在这里,许多编译器可能会告诉您要避免它,但许多编译器都需要它)。

因为
clientData
char*
clientData[i]
是一个简单的字符。这与
createClient()
prototype冲突,prototype需要指向以NULL结尾的字符串的指针

请注意,在对它们进行mallock操作之后,您永远不会初始化它们。这在运行时是个问题,因为
strdup()
需要复制某些内容(至少是一个空字符串!)


第二个错误要求您将malloc的结果强制转换为
客户机*
(即使在这里,许多编译器可能会告诉您要避免它,但许多编译器都需要它)。

读取和创建操作可以结合使用。然后,在读取文件时,可以使用
realloc
增加客户端的数量。分配一个额外的结构作为哨兵。或者跟踪分配的结构数量。
对于每个结构,尝试从文件中读取四行,然后
strdup
读取指向结构指针的行

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

typedef struct
{
    char *name;
    char *phoneNumber;
    char *location;
    char *traveltype;
} Client;

char *linefree ( char *line) {
    free ( line);
    return NULL;
}

Client *clientfree ( Client *client) {
    size_t count = 0;
    //the sentinel element will have name as NULL
    while ( client && client[count].name) {
        client[count].name = linefree ( client[count].name);
        client[count].phoneNumber = linefree ( client[count].phoneNumber);
        client[count].location = linefree ( client[count].location);
        client[count].traveltype = linefree ( client[count].traveltype);
        count++;
    }
    free ( client);
    return NULL;
}

void showclient ( Client *client) {
    size_t count = 0;
    //the sentinel element will have name as NULL
    while ( client && client[count].name) {
        printf ( "%s\n", client[count].name);
        if ( client[count].phoneNumber) {
            printf ( "   %s\n", client[count].phoneNumber);
        }
        if ( client[count].location) {
            printf ( "   %s\n", client[count].location);
        }
        if ( client[count].traveltype) {
            printf ( "   %s\n", client[count].traveltype);
        }
        count++;
    }
}

Client *readClientData ( char *filename) {
    size_t count = 0;
    FILE *pf = NULL;
    Client *client = NULL;
    Client *temp = NULL;
    if ( NULL == ( pf = fopen ( filename, "r"))) {
        perror ( filename);
        exit ( EXIT_FAILURE);
    }
    while ( 1) {
        // count + 2 to have sentinel element
        if ( NULL == ( temp = realloc ( client, sizeof *client * ( count + 2)))) {
            fprintf ( stderr, "realloc problem\n");
            return client;
        }
        client = temp;
        //set current element to NULL
        client[count].name = NULL;
        client[count].phoneNumber = NULL;
        client[count].location = NULL;
        client[count].traveltype = NULL;
        count++;
        //following serves as sentinel element
        client[count].name = NULL;
        client[count].phoneNumber = NULL;
        client[count].location = NULL;
        client[count].traveltype = NULL;

        char line[1024] = "";

        if ( ! fgets ( line, sizeof line, pf)) {
            fprintf ( stderr, "fgets EOF\n");
            break;
        }
        if ( NULL == ( client[count - 1].name = strdup ( line))) {
            fprintf ( stderr, "strdup name problem\n");
            break;
        }
        if ( ! fgets ( line, sizeof line, pf)) {
            fprintf ( stderr, "fgets EOF\n");
            break;
        }
        if ( NULL == ( client[count - 1].phoneNumber = strdup ( line))) {
            fprintf ( stderr, "strdup phoneNumber problem\n");
            break;
        }
        if ( ! fgets ( line, sizeof line, pf)) {
            fprintf ( stderr, "fgets EOF\n");
            break;
        }
        if ( NULL == ( client[count - 1].location = strdup ( line))) {
            fprintf ( stderr, "strdup location problem\n");
            break;
        }
        if ( ! fgets ( line, sizeof line, pf)) {
            fprintf ( stderr, "fgets EOF\n");
            break;
        }
        if ( NULL == ( client[count - 1].traveltype = strdup ( line))) {
            fprintf ( stderr, "strdup traveltype problem\n");
            break;
        }
    }
    fclose ( pf);
    return client;
}

int main ( void) {
    char filename[1024] = "";
    printf ( "Enter a filename\n");
    if ( ! fgets ( filename, sizeof filename, stdin)) {
        fprintf ( stderr, "fgetline filename problem\n");
        exit ( EXIT_FAILURE);
    }
    filename[strcspn ( filename, "\n")] = 0;//remove trailing newline
    Client *client = readClientData ( filename);

    showclient ( client);

    client = clientfree ( client);

    return 0;
}
#包括
#包括
#包括
类型定义结构
{
字符*名称;
字符*电话号码;
字符*位置;
字符*旅行类型;
}客户;
无字符*行(字符*行){
自由线;
返回NULL;
}
客户端*客户端免费(客户端*客户端){
大小\u t计数=0;
//sentinel元素的名称将为NULL
while(客户端和客户端[count].name){
客户端[count].name=linefree(客户端[count].name);
客户端[count].phoneNumber=linefree(客户端[count].phoneNumber);
客户端[count].location=linefree(客户端[count].location);
客户端[count].traveltype=linefree(客户端[count].traveltype);
计数++;
}
免费(客户);
返回NULL;
}
无效showclient(客户端*客户端){
大小\u t计数=0;
//sentinel元素的名称将为NULL
while(客户端和客户端[count].name){
printf(“%s\n”,客户端[count].name);
if(客户端[count].phoneNumber){
printf(“%s\n”,客户端[count]。电话号码);
}
if(客户端[计数].位置){
printf(“%s\n”,客户端[count]。位置);
}
if(客户端[计数].traveltype){
printf(“%s\n”,客户端[count].traveltype);
}
计数++;
}
}
客户端*readClientData(字符*文件名){
大小\u t计数=0;
FILE*pf=NULL;
Client*Client=NULL;
客户端*temp=NULL;
if(NULL==(pf=fopen(文件名,“r”)){
perror(文件名);
退出(退出失败);
}
而(1){
//计数+2以拥有sentinel元素
if(NULL==(temp=realloc(客户端,sizeof*客户端*(计数+2))){
fprintf(标准,“realloc问题”);
返回客户;
}
客户=临时工;
//将当前元素设置为NULL
客户端[count]。名称=NULL;
客户端[count]。电话号码=NULL;
客户端[count]。位置=NULL;
客户端[count]。traveltype=NULL;
计数++;
//下面是哨兵部队
客户端[count]。名称=NULL;
客户端[count]。电话号码=NULL;
客户端[count]。位置=NULL;
客户端[count]。traveltype=NULL;
字符行[1024]=“”;
如果(!fgets(线、线尺寸、pf)){
fprintf(标准术语,fgets EOF);
打破
}
if(NULL==(客户端[count-1].name=strdup(行))){
fprintf(stderr,“strdup名称问题”);
打破
}
如果(!fgets(线、线尺寸、pf)){
fprintf(标准术语,fgets EOF);
打破
}
if(NULL==(客户端[count-1].phoneNumber=strdup(行))){
fprintf(stderr,“strdup电话号码问题”);
打破
}
如果(!fgets(线、线尺寸、pf)){
fprintf(标准术语,fgets EOF);
打破
}
if(NULL==(客户端[count-1].location=strdup(行))){
fprintf(stderr,“strdup位置问题”);
打破
}
如果(!fgets(线、线尺寸、pf)){
fprintf(标准术语,fgets EOF);
打破
}
if(NULL==(客户端[count-1].traveltype=strdup(行))){
fprintf(stderr,“strdup旅行类型问题”);
打破
}
}
fclose(pf);
返回客户;
}
内部主(空){
字符文件名[1024]=“”;
printf(“输入文件名\n”);
如果(!fgets(文件名、文件名大小、标准输入)){
fprintf(stderr,“fgetline文件名问题”);
退出(退出失败);
}
filename[strcspn(filename,“\n”)]=0;//删除尾部换行符
Client*Client=readClientData(文件名);
showclient(客户);
client=clientfree(客户端);
返回0;
}

读取和创建操作可以结合使用。然后,在读取文件时,可以使用
realloc
增加客户端的数量。分配一个额外的结构作为哨兵。或者跟踪分配的结构数量。
对于每个结构,尝试从文件中读取四行,然后
strdup
structure p的行