Reputation: 1166
Summary:
printf()
.My XML File looks like this:
<Server>
<Host>ip1</Host>
<User>user1</User>
<Pass>pass1</Pass>
</Server>
<Server>
<Host>ip2</Host>
<User>user2</User>
<Pass>pass2</Pass>
</Server>
Now, my code is able to get: ip1, user1, pass1.
How can I modify my code, so that I can also get ip2, user2, pass2 then ip3, user3, pass3 and so on until I reach the end of the file ?
The code is the next one:
int getContent()
{
//variables for reading the XML file
char *buffer=0;
long length;
FILE *xmlFile=fopen("C:/Users/IEUser/AppData/Roaming/recentservers.xml","r");
//constants for parsing XML
const char *HOSTSTART = "<Host>";
const char *HOSTEND = "</Host>";
const char *USERSTART = "<User>";
const char *USEREND = "</User>";
const char *PASSSTART = "<Pass encoding=\"base64\">";
const char *PASSEND = "</Pass>";
char *target_host = NULL,*target_user = NULL,*target_pass = NULL, *start, *end;
//read the xml file
if(xmlFile)
{
fseek(xmlFile,0,SEEK_END);
length=ftell(xmlFile);
fseek(xmlFile,0,SEEK_SET);
buffer=malloc(length);
if(buffer)
{
fread(buffer,1,length,xmlFile);
}
fclose(xmlFile);
}
//get the HOST
if(buffer)
{
if(start=strstr(buffer,HOSTSTART))
{
start += strlen(HOSTSTART);
if(end=strstr(start, HOSTEND))
{
target_host = (char *)malloc(end-start+1);
memcpy(target_host,start,end-start);
target_host[end-start]='\0';
}
}
if(target_host)
printf("%s\n",target_host);
//free(target_host);
}
//get the USER
if(buffer)
{
if(start=strstr(buffer,USERSTART))
{
start += strlen(USERSTART);
if(end=strstr(start, USEREND))
{
target_user = (char *)malloc(end-start+1);
memcpy(target_user,start,end-start);
target_user[end-start]='\0';
}
}
if(target_user)
printf("%s\n",target_user);
//free(target_user);
}
//get the PASS
if(buffer)
{
if(start=strstr(buffer,PASSSTART))
{
start += strlen(PASSSTART);
if(end=strstr(start, PASSEND))
{
target_pass = (char *)malloc(end-start+1);
memcpy(target_pass,start,end-start);
target_pass[end-start]='\0';
}
}
if(target_pass)
printf("%s\n",target_pass);
//free(target_pass);
}
// here I would like a for which will printf as many target information as they are in that XML File
printf("%s | %s | %s",target_host,target_user,target_pass);
printf("\n\n");
return 0;
}
int main()
{
getContent();
return 0;
}
//EDIT1:
int readTag(char *buffer, const char *tagStart, const char *tagEnd){
int start, end;
char *target = NULL;
start = 0;
end = 0;
if(start=strstr(buffer,tagStart))
{
start += strlen(tagStart);
if(end=strstr(start, tagEnd))
{
target = malloc(end-start+1); //don't cast malloc
memcpy(target,start,end-start);
target[end-start]='\0';
printf("Target between tag %s and %s = %s", tagStart, tagEnd, target);
//sendTargetToGET(tagStart, tagEnd, target);
free(target);
}
}
return (end - start); // returns nr characters between the tags
}
int getTagID(char *buffer){
const char *HOSTSTART = "<Host>";
const char *HOSTEND = "</Host>";
const char *USERSTART = "<User>";
const char *USEREND = "</User>";
const char *PASSSTART = "<Pass encoding=\"base64\">";
const char *PASSEND = "</Pass>";
if(strstr(buffer, HOSTSTART) != NULL && strstr(buffer, HOSTEND) != NULL)
{
return 1;
}
else if(strstr(buffer, USERSTART) != NULL && strstr(buffer, USEREND) != NULL)
{
return 2;
}
else if(strstr(buffer, PASSSTART) != NULL && strstr(buffer, PASSEND) != NULL)
{
return 3;
}
else
return 0;
}
int main()
{
char *buffer=0;
const char *HOSTSTART = "<Host>";
const char *HOSTEND = "</Host>";
const char *USERSTART = "<User>";
const char *USEREND = "</User>";
const char *PASSSTART = "<Pass encoding=\"base64\">";
const char *PASSEND = "</Pass>";
FILE *xmlFile=fopen("C:/Users/IEUser/AppData/Roaming/recentservers.xml","r");
int tagID = 0;
while (fgets(buffer, sizeof(buffer), xmlFile) != NULL)
{
tagID = getTagID(buffer);
if(tagID == 1)
{
readTag(buffer, HOSTSTART, HOSTEND);
}
else if(tagID == 2)
{
readTag(buffer, USERSTART, USEREND);
}
else if(tagID == 3)
{
}
}
return 0;
}
I've got an assertion failure unfortunately and I don't know what is the reason
Upvotes: 1
Views: 126
Reputation: 4659
What I would suggest is:
1) Put the tag read parts in a function so you can don't have the same code for every tag:
int readTag(char *buffer, const char *tagStart, const char *tagEnd){
int start, end;
char *target = NULL;
start = 0;
end = 0;
if(start=strstr(buffer,tagStart))
{
start += strlen(tagStart);
if(end=strstr(start, tagEnd))
{
target = malloc(end-start+1); //don't cast malloc
memcpy(target,start,end-start);
target[end-start]='\0';
printf("Target between tag %s and %s = %s", tagStart, tagEnd, target);
//sendTargetToGET(tagStart, tagEnd, target);
free(target);
}
}
return (end - start); // returns nr characters between the tags
}
2) Read the file line by line, check if the line contains tags you need (maybe with a function) and call the associated tag read function.
int tagID = 0;
while (fgets(buffer, sizeof(buffer), xmlFile) != NULL){
tagID = getTagID(buffer);
if(tagID == 1){//or use an enum here
readTag(buffer, HOSTSTART, HOSTEND);
}else if(tagID == 2){
readTag(buffer, USERSTART, USEREND);
}else if(tagID == 3){ //and so on
}
}
int getTagID(char *buffer){
if(strstr(buffer, HOSTSTART) != NULL && strstr(buffer, HOSTEND) != NULL){
return 1;
}else if(strstr(buffer, USERSTART) != NULL && strstr(buffer, USERSTART) != NULL){
return 2;
}else if(/*and so on*/){
}else return 0;
}
Upvotes: 2