gpt4 book ai didi

C : Error when i try separate program to modules

转载 作者:太空宇宙 更新时间:2023-11-04 04:24:53 24 4
gpt4 key购买 nike

我需要编写一个程序来从 xml 文件中填充结构并读取 xml 文件,但这不是问题。

首先我写了一个没有模块的程序(正在编译):

主.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <strings.h>
#include <libxml/tree.h>
#include <string.h>

#include "startupDirector.h"

static void startup_from_xml(Startup_T *startup, xmlNode * curNode)
{
char * data;
for(curNode = curNode->children; curNode != NULL; curNode = curNode->next)
{
// Get "name" string field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"name"))
{
data = (char *)xmlNodeGetContent(curNode);
strcpy(startup->name, data);
continue;
}
// Get "budget" integer field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"budget"))
{
data = (char *)xmlNodeGetContent(curNode);
startup->budget = atoi(data);
continue;
}
}
}

static Director_T *director_from_xml(Director_T *curDirector, xmlNode * curNode)
{
char *data;
char *properties;

// Get "name" string attribute.
properties = (char *) xmlGetProp(curNode, (const xmlChar *)"name");
strcpy(curDirector->name, properties);
// Get "surname" string attribute.
properties = (char *)xmlGetProp(curNode, (const xmlChar *)"surname");
strcpy(curDirector->surname, properties);
for(curNode = curNode->children; curNode != NULL; curNode = curNode->next)
{
// Get "nationality" string field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"nationality"))
{
data = (char *)xmlNodeGetContent(curNode);
strcpy(curDirector->nationality, data);
continue;
}
// Get "birthdate" UTC ISO 8601 field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"birthdate"))
{
data = (char *)xmlNodeGetContent(curNode);
sscanf(data, "%d-%d-%d",
&curDirector->birthDate.tm_year,
&curDirector->birthDate.tm_mday,
&curDirector->birthDate.tm_mon);
continue;
}
// Get "enthusiasm" integer field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"enthusiasm"))
{
data = (char *)xmlNodeGetContent(curNode);
curDirector->enthusiasm = atoi(data);
continue;
}
// Get "experience" double field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"experience"))
{
data = (char *)xmlNodeGetContent(curNode);
curDirector->experience = atof(data);
continue;
}
// Get "money" integer field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"money"))
{
data = (char *)xmlNodeGetContent(curNode);
curDirector->money = atoi(data);
continue;
}
// Get "startup" (string,integer) complex field.
if(!xmlStrcmp(curNode->name, (xmlChar *)"startup"))
{
startup_from_xml(&(curDirector->startup), curNode);
continue;
}
}
return (curDirector);
}

Director_T *director_new(void)
{
Director_T *director = (Director_T *)malloc(sizeof(struct Director_S));
strcpy(director->name, "");
strcpy(director->surname, "");
strcpy(director->nationality, "");
memset(&director->birthDate, 0, sizeof(director->birthDate));
director->enthusiasm = 0;
director->experience = 0;
director->money = 0;
strcpy(director->startup.name, "");
director->startup.budget = 0;
return (director);
}

void xmlParse(Director_T **directorSet, const char * XMLFileName)
{
xmlDoc * doc = xmlReadFile(XMLFileName, "UTF-8", 0);
if(doc == NULL)
{
xmlFreeDoc(doc);
return;
}
xmlNode *xml_root = xmlDocGetRootElement(doc);
xmlNode *curNode;
int i;
for(i = 0, curNode = xml_root->children; curNode != NULL; curNode = curNode->next)
{
if(!xmlStrcmp(curNode->name, (const xmlChar *)"director"))
{
director_from_xml(directorSet[i++], curNode);
}
}
xmlFreeDoc(doc);
}

void printDirectorInfo(Director_T *director)
{
printf("\t[%s]\n"
"\t[%s]\n"
"\t[%s]\n"
"\t%d-%d-%d\n"
"\t%i\n"
"\t%f\n"
"\t%i\n"
"\t[%s]\n"
"\t%i\n\n",
director->name,
director->surname,
director->nationality,
director->birthDate.tm_year, director->birthDate.tm_mon, director->birthDate.tm_mday,
director->enthusiasm,
director->experience,
director->money,
director->startup.name,
director->startup.budget
);
}

void director_delete(Director_T *director)
{
free(director);
}

int main()
{
const char *filePath = "StartupDirector.xml";
Director_T *directors[DIRECTORS_COUNT];

// Init directors array.
for(int i = 0; i < DIRECTORS_COUNT; i++)
{
directors[i] = director_new();
}

// Parse elements from .xml file.
xmlParse(directors, filePath);

// Print parsed info.
for(int i = 0; i < DIRECTORS_COUNT; i++)
{
printf("STARTUP_DIRECTOR #%i\n", (i+1));
printDirectorInfo(directors[i]);
}

// Free allocated memory.
for(int i = 0; i < DIRECTORS_COUNT; i++)
{
director_delete(directors[i]);
}
return 0;
}

生成文件:

all:
gcc main.c -g -Werror -c -I /usr/include/libxml2
gcc *.o -lxml2
rm *.o

当我编译这个 main.c 时一切顺利,但后来我试图将我的程序分成模块并遇到问题:

新主.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <strings.h>
#include <libxml/tree.h>
#include <string.h>

#include "startupDirector.h"

int main()
{
const char *filePath = "StartupDirector.xml";
Director_T *directors[DIRECTORS_COUNT];

// Init directors array.
for(int i = 0; i < DIRECTORS_COUNT; i++)
{
directors[i] = director_new();
}

// Parse elements from .xml file.
xmlParse(directors, filePath);

// Print parsed info.
for(int i = 0; i < DIRECTORS_COUNT; i++)
{
printf("STARTUP_DIRECTOR #%i\n", (i+1));
printDirectorInfo(directors[i]);
}

// Free allocated memory
for(int i = 0; i < DIRECTORS_COUNT; i++)
{
director_delete(directors[i]);
}
return 0;
}

startupDirector.c(用于模块)

#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <time.h>

#include <libxml/tree.h>
#include "startupDirector.h"

// private:
static void startup_from_xml(Startup_T *startup, xmlNode * curNode)
{
char * data;
for(curNode = curNode->children; curNode != NULL; curNode = curNode->next)
{
// Get "name" string field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"name"))
{
data = (char *)xmlNodeGetContent(curNode);
strcpy(startup->name, data);
continue;
}
// Get "budget" integer field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"budget"))
{
data = (char *)xmlNodeGetContent(curNode);
startup->budget = atoi(data);
continue;
}
}
}

static Director_T *director_from_xml(Director_T *curDirector, xmlNode * curNode)
{
char *data;
char *properties;

// Get "name" string attribute.
properties = (char *) xmlGetProp(curNode, (const xmlChar *)"name");
strcpy(curDirector->name, properties);
// Get "surname" string attribute.
properties = (char *)xmlGetProp(curNode, (const xmlChar *)"surname");
strcpy(curDirector->surname, properties);
for(curNode = curNode->children; curNode != NULL; curNode = curNode->next)
{
// Get "nationality" string field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"nationality"))
{
data = (char *)xmlNodeGetContent(curNode);
strcpy(curDirector->nationality, data);
continue;
}
// Get "birthdate" UTC ISO 8601 field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"birthdate"))
{
data = (char *)xmlNodeGetContent(curNode);
sscanf(data, "%d-%d-%d",
&curDirector->birthDate.tm_year,
&curDirector->birthDate.tm_mday,
&curDirector->birthDate.tm_mon);
continue;
}
// Get "enthusiasm" integer field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"enthusiasm"))
{
data = (char *)xmlNodeGetContent(curNode);
curDirector->enthusiasm = atoi(data);
continue;
}
// Get "experience" double field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"experience"))
{
data = (char *)xmlNodeGetContent(curNode);
curDirector->experience = atof(data);
continue;
}
// Get "money" integer field.
if(!xmlStrcmp(curNode->name, (const xmlChar *)"money"))
{
data = (char *)xmlNodeGetContent(curNode);
curDirector->money = atoi(data);
continue;
}
// Get "startup" (string,integer) complex field.
if(!xmlStrcmp(curNode->name, (xmlChar *)"startup"))
{
startup_from_xml(&(curDirector->startup), curNode);
continue;
}
}
return (curDirector);
}
// public:
Director_T *director_new(void)
{
Director_T *director = (Director_T *)malloc(sizeof(struct Director_S));
strcpy(director->name, "");
strcpy(director->surname, "");
strcpy(director->nationality, "");
memset(&director->birthDate, 0, sizeof(director->birthDate));
director->enthusiasm = 0;
director->experience = 0;
director->money = 0;
strcpy(director->startup.name, "");
director->startup.budget = 0;
return (director);
}

void director_delete(Director_T *director)
{
free(director);
}

void xmlParse(Director_T **directorSet, const char * XMLFileName)
{
xmlDoc * doc = xmlReadFile(XMLFileName, "UTF-8", 0);
if(doc == NULL)
{
xmlFreeDoc(doc);
return;
}
xmlNode *xml_root = xmlDocGetRootElement(doc);
xmlNode *curNode;
int i;
for(i = 0, curNode = xml_root->children; curNode != NULL; curNode = curNode->next)
{
if(!xmlStrcmp(curNode->name, (const xmlChar *)"director"))
{
director_from_xml(directorSet[i++], curNode);
}
}
xmlFreeDoc(doc);
}

void printDirectorInfo(Director_T *director)
{
printf("\t[%s]\n"
"\t[%s]\n"
"\t[%s]\n"
"\t%d-%d-%d\n"
"\t%i\n"
"\t%f\n"
"\t%i\n"
"\t[%s]\n"
"\t%i\n\n",
director->name,
director->surname,
director->nationality,
director->birthDate.tm_year, director->birthDate.tm_mon, director->birthDate.tm_mday,
director->enthusiasm,
director->experience,
director->money,
director->startup.name,
director->startup.budget
);
}

startupDirector.h

#ifndef STARTUPDIRECTOR_H
#define STARTUPDIRECTOR_H

#include <time.h> // time_t

#define DIRECTOR_NAME_LEN 50
#define DIRECTOR_SURNAME_LEN 50
#define DIRECTOR_NATIONALITY_LEN 50
#define STARTUP_NAME_LEN 100

#define DIRECTORS_COUNT 4

typedef struct Startup_S
{
char name[STARTUP_NAME_LEN];
int budget;
} Startup_T;

typedef struct Director_S
{
char name[DIRECTOR_NAME_LEN];
char surname[DIRECTOR_SURNAME_LEN];
char nationality[DIRECTOR_NATIONALITY_LEN];
struct tm birthDate;
int enthusiasm;
float experience;
int money;
struct Startup_S startup;
} Director_T;

Director_T *director_new(void);
void director_delete(Director_T *director);
Startup_T *startup_new(void);
void startup_delete(Startup_T *startup);

void xmlParse(Director_T *directorSet[], const char * XMLFileName);
void printDirectorInfo(Director_T *director);

#endif

在使用 makefile 编译这个文件后我有一个错误终端:

brusentcov@brusentcov:~/projects/xml_startup$ make
gcc main.c -g -Werror -c -I /usr/include/libxml2
gcc *.o -lxml2
main.o: In function `main':
/home/brusentcov/projects/xml_startup/main.c:168: undefined reference to `director_new'
/home/brusentcov/projects/xml_startup/main.c:172: undefined reference to `xmlParse'
/home/brusentcov/projects/xml_startup/main.c:178: undefined reference to `printDirectorInfo'
/home/brusentcov/projects/xml_startup/main.c:184: undefined reference to `director_delete'
collect2: error: ld returned 1 exit status

我希望有人能帮助我。感谢您阅读本文。

最佳答案

问题出在 makefile 上。

这是我使用的 make 文件(在修复评论中提到的 #include 语句之后

#all:
# gcc xml_main.c -g -Werror -c -I /usr/include/libxml2
# gcc *.o -lxml2
# rm *.o

CC := /usr/bin/gcc
RM := /bin/rm

CFLAGS := -c -Wall -Wextra -pedantic -Wconversion -std=gnu11

SRC := main.c startupDirector.c

OBJ := $(SRC:.c=.o)

target := xmlProgram

.PSEUDO: all clean

all: $(target)

$(target): $(OBJ)
$(CC) -o $@ $^ -L /usr/lib/x86_64-linux-gnu/ -lxml2

%.o:%.c
$(CC) $(CFLAGS) -o $@ $< -I. -I /usr/include/libxml2

clean:
$(RM) -f $(OBJ) $(target)

这是调用 make 的完整输出

/usr/bin/gcc -c -Wall -Wextra -pedantic -Wconversion -std=gnu11 -o main.o main.c -I. -I /usr/include/libxml2
/usr/bin/gcc -c -Wall -Wextra -pedantic -Wconversion -std=gnu11 -o startupDirector.o startupDirector.c -I. -I /usr/include/libxml2
startupDirector.c: In function ‘director_from_xml’:
startupDirector.c:73:39: warning: conversion to ‘float’ from ‘double’ may alter its value [-Wfloat-conversion]
curDirector->experience = atof(data);
^
/usr/bin/gcc -o xmlProgram main.o startupDirector.o -L /usr/lib/x86_64-linux-gnu/ -lxml2

强烈建议您修复有关从 doublefloat 的转换的警告

因为我没有预期的输入文件,这里是输出:

I/O warning : failed to load external entity "StartupDirector.xml"
STARTUP_DIRECTOR #1
[]
[]
[]
0-0-0
0
0.000000
0
[]
0

STARTUP_DIRECTOR #2
[]
[]
[]
0-0-0
0
0.000000
0
[]
0

STARTUP_DIRECTOR #3
[]
[]
[]
0-0-0
0
0.000000
0
[]
0

STARTUP_DIRECTOR #4
[]
[]
[]
0-0-0
0
0.000000
0
[]
0

注:我在ubuntu linux 16.04上编译、链接、运行

关于C : Error when i try separate program to modules,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42703335/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com