我需要編寫一個程序,從xml文件中填充結構並讀取xml文件,但這不是問題。C:錯誤,當我嘗試單獨的程序模塊
首先,我不寫模塊的程序(它的編譯):
的main.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;
}
的Makefile:
all:
gcc main.c -g -Werror -c -I /usr/include/libxml2
gcc *.o -lxml2
rm *.o
當我編譯這一切的main.c要美觀大方,但後來我試圖分開我的程序模塊,並得到了一個問題:
new main.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編譯這個文件後,我有一個錯誤 終端:
[email protected]:~/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
我希望有人能幫助我。感謝您的關注,如果您閱讀此內容。
您需要**編譯並鏈接**'startupDirector.c',而不僅僅是'main.c' – StoryTeller
'startupDirector.c'文件缺少必需的語句:'#include(不是字符串。 h)對於函數'strcpy()'和'memset()',它有一個聲明:'#include '這是不使用的。 –
user3629249