我不确定这是否是使用值创建和初始化结构的正确方法:
#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));
我在这里想念什么?
答案 0 :(得分:1)
由于working
是clientData
,所以char *
是一个简单字符。这与clientData[i]
原型(期望使用指向以NULL结尾的字符串的char的指针)相冲突。
请注意,在分配它们之后,您永远不会初始化它们。这在运行时将是一个问题,因为createClient ()
需要复制一些内容(至少要包含一个空字符串!)。
第二个错误要求您将malloc的结果强制转换为strdup ()
(即使在很多情况下也可能会告诉您避免这样做,许多编译器都需要它)。
答案 1 :(得分:1)
读取和创建操作可以合并。然后,在读取文件时,可以使用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;
}