Solved

parse a template file

Posted on 2000-02-24
9
348 Views
Last Modified: 2010-04-02
Hi,

This is what I want to achieve:

I have a text file as following:
=====================================
<html>
<body>
  Name:<$MY_TAG FIELD=name>
  TEL :<$MY_TAG FIELD=tel>
</body>
</html>
=====================================
I want to write a c program that read in this template file and replace <$MY_TAG ??????> with the data I retrieved from a database. And then prints out this file.

Can someone please tell me what's the good algorithm to use? Should I read this file into memory first and processes it from there.
Or is there any third-party C library that can help me do this?

Thanks in advance.

0
Comment
Question by:samantha
  • 3
  • 2
  • 2
  • +2
9 Comments
 
LVL 3

Expert Comment

by:ufolk123
ID: 2557081
Hi samantha,

I do not feel this problem as that of a parsing problem .May be the reverse and correct logic of your problem is to read out an array of name and tel pairs and generate the an output in the form of template

<html>
<body>
  Name:<$MY_TAG FIELD=name>
  TEL :<$MY_TAG FIELD=tel>
</body>
</html>

So you do it this way,
Read each record from the database and
write a code genrerator(so called) which will take in ( name1,telno1) and print the result in the form of

<html>
<body>
  Name:<$MY_TAG FIELD=name1>
  TEL :<$MY_TAG FIELD=tel1>
</body>
</html>

This you acheive simple by a series of printfs.
printf("<html> \n <body> \n   Name:<$MY_TAG FIELD=");
printf("%s",name1);
printf(>TEL :<$MY_TAG FIELD=");
printf("%s",tel1);
printf("> \n </body> \n</html> ");

0
 

Author Comment

by:samantha
ID: 2558328
Hi ufolk123,

Thanks for the answer. But that's not what I want. Maybe I didn't state the problem clearly. This is actually a CGI program.

Let's call this program test.c. And the template file template.txt:
=============================
<html>
<body>
  Name:<$MY_TAG FIELD=name>
  TEL :<$MY_TAG FIELD=phone>
</body>
</html>
=============================

And a database table like this:
==============================
ID       NAME        PHONE
01       Samantha    (111)111-1111
02       ufolk123    (222)222-2222
......
==============================

The program is invoked like this:

http://xx.com/test.exe?id=02&template= template.txt

This program then retrieves the Record 02 from the database and use the "template.txt" to generate the following result page:
=============================
<html>
<body>
  Name:ufolk123
  TEL :(222)222-2222
</body>
</html>
=============================

I don't want to hard code this file using printf() beacuse everytime you want to change the layout, you have to do it inside the code and recompile the program. With this template file, users of "test.exe" can always provide their own "template.txt".

Thanks,

0
 

Expert Comment

by:DontPanic
ID: 2558686
Hmmm. Looks like a problem better suited to XML.
0
 
LVL 3

Expert Comment

by:arnond
ID: 2558895
I would use a kind of final state machine that will parse the input file.
I would read the input file char by char and look first, for a '<' then I 'd look of a '$', 'M', 'Y','_' etc....untill i get the string '<$MY_TAG FIELD=' now, I know that the following string (up to the next '>') is the requiered field. After knowing wat field it is, just use the database's interface as you normaly do.
BTW, while you look for the first '<' just read the char and output it if it's not '<'. Your code should look something like this:
----------------------------
char ch,needed_ch,temp_array[100];
int state=0; /* state will record the state of the FSM (i.e., how many chars we've read so far that match the string we're looking for.*/
FILE* in_file,out_file; /* assuming files are open...*/

while ((ch=getc(infile))!=EOF)
{
  switch (state)
  {
     case (0):
       needed_ch='<';
       break;
     case (1):
       needed_ch='$';
       break;
     case (2):
       needed_ch='M';
       break;
/* continue with cases */
  }
  if (ch==needed_ch) /* did we get what we wanted ? */
  {
     temp_array[state]=ch;
     temp_array[state+1]='\0'; /* terminating NULL*/
     if (state==MAX_NUM_OF_STATES) /* which is the length of '<$MY_TAG FIELD' */
     {
        /* do data base stuff here and output the correct field's value */
     }
  }  else /* didn't get what we wanted.*/
     {
       putc (ch,out_file); /* just output the given char*/
       state=0; /* start over*/
     }
}

----------------------------
Please note that this code wasn't tested and compiled so it may have some erros but it should give you a clear idea.

Arnon David.
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
LVL 11

Accepted Solution

by:
alexo earned 100 total points
ID: 2559065
Normally, this is a job for Lex/Yacc.
But since you want it in C, do something like the following:
(quick & dirty: no error checking performed, file names are constants...)

    #include <stdio.h>
    #include <string.h>

    #define IN "in.txt"
    #define OUT "out.txt"
    #define MAX_LEN 256
    #define TOKEN1 "<$MY_TAG FIELD="
    #define TOKEN2 '>'

    FILE* in = fopen(IN, "r");
    FILE* out = fopen(OUT, "w");
    char line[MAX_LEN];

    while (fgets(line, sizeof line, in))
    {
        char* p1 = strstr(line, TOKEN1);
        if (p1)
        {
            char value[MAX_LEN];
            char* field = strdup(p1 + sizeof TOKEN1);
            char* p2 = strchr(field, TOKEN2);
            *p1 = *p2 = 0;
    /*
            Now, 'field' contains the name of the desired
            field name.  You get it's value from the DB
            into the 'value' variable.
    */
            strcat(p1, value);
            strcat(p1, p2 + 1);
        }

        fputs(line, out);
    }

    fclose(in);
    fclose(out);
0
 

Author Comment

by:samantha
ID: 2559500
Thanks a lot, guys.

arnond & alexo, both your answers are excellent.  I wish they had a way to let me split the points to both of you.

Since alexo has locked it, I am giving the points to him.  Sorry, arnond. But if you can tell me how I can give you the points, I will also give 100 points.

Thanks again.  

0
 
LVL 3

Expert Comment

by:arnond
ID: 2559691
If you want to spend an extra 100 points, just post another (empty) question titled something like "points for arnond" and I'll "answer" it and you'll accept.
But, do that only if you want to.

Thanks,
Arnon David.
0
 
LVL 11

Expert Comment

by:alexo
ID: 2561309
If you don't have enough points, I can give Arnon 100+A of my own (I got some spare since I rarely ask questions).  Post a comment here in case you like the idea.
0
 
LVL 3

Expert Comment

by:arnond
ID: 2561355
it's ok, she already posted one.

thanks anyway,
Arnon David.
0

Featured Post

Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
In desperate need of help 8 132
Trouble linking program with -lcrypt 3 142
distributed computing in Python 4 115
How to programmatically differentiate between C and Java 10 188
Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now