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的行