Solved

HTMLScript question (the closest topic area I could find was CGI)

Posted on 1998-03-07
19
215 Views
Last Modified: 2013-12-25
this is actually two questions:

one, I have a .dat file generated by an HTMLScript script, it consists of several hundred records with 3 fields each.  What I need is a script that would alphabetize the records according to the third field.

and two, if I pass a string to the script in the URL (eg script.hts?this is the string I am passing) when I use <EVAL arg2> to display it I get '%20' instead of spaces, how do I get rid of those?  I tried using FMT but couldn't get it to work correctly.
0
Comment
Question by:Begemot
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 8
  • 2
19 Comments
 
LVL 5

Expert Comment

by:julio011597
ID: 1832083
I could give you some C code:

1. a program to sort the file;

2. a function to be put into your CGI to get rid of character encoding.

Let me know if you are interested in it.
0
 

Author Comment

by:Begemot
ID: 1832084
the problem with that is that I do not (and can't) use CGI, I use HTMLScript, but a simple C program that does the sorting would actually be helpful; I does not really matter whether I do the sorting locally or from my site.

so if you could send me the C program I would appreciate it, the format of the file is as follows:

string|number|string
string|number|string
.
.
.

and it has to be sorted alphabeticaly by the *second* string, ie the third field.

thanks
0
 
LVL 5

Expert Comment

by:julio011597
ID: 1832085
Could you tell how many lines the file should be expected to contain at most?

BTW, sorry, i've never seen HTMLScript; anyway, if you start telling which functions it supports for string and character handling, or - better - if there's some documentation on-line, then we could try building some working code together.
0
Webinar: Aligning, Automating, Winning

Join Dan Russo, Senior Manager of Operations Intelligence, for an in-depth discussion on how Dealertrack, leading provider of integrated digital solutions for the automotive industry, transformed their DevOps processes to increase collaboration and move with greater velocity.

 

Author Comment

by:Begemot
ID: 1832086
HTMLScript is pretty simplistic, but it is very powerful.  Check out their site at - http://www.htmlscript.com (big surprise there) they have the complete documentation on it.  Oh yeah, i can't use Miva(version 3.0 of HTMLScript) yet, so we are going to have to stick with 2.99
0
 
LVL 5

Expert Comment

by:julio011597
ID: 1832087
Ok... in the meantime, i'll also wait for the number of lines to be sorted; this is crucial to design an efficient sorting program.

And, which OS will the program run on?
0
 
LVL 5

Expert Comment

by:julio011597
ID: 1832088
Sorry, rereading your question, i see you talk about hundreds of lines: that's enough to know.

Just waiting for the target OS.
0
 

Author Comment

by:Begemot
ID: 1832089
ok, I think I know enough of HTMLScript to do the thing myself, but I need a very efficient sort script.  If you could tell me how that is done, just in simple english, or even a C example would be fine; I just need the general idea.  I'll be able to take it from there.
0
 
LVL 5

Expert Comment

by:julio011597
ID: 1832090
This is far from being *real life* C code, so please don't use it in your C programs :)
instead i've tried to make it as readable as possible:

--//--
/*
 * str[]: the string to unescape
 * rstr[]: the result string
 * /
char *
unescape(char str[])
{
  /* local variables */
  static char rstr[128];
  int curs;
  int str_length;

  /* initialization */
  strcpy(rstr, "");
  curs = 0;
  str_length = strlen(str);

  while(curs < str_length) {
    /* local variables */
    char tmp[2] = ""; /* i need this temporary var; hopefully you won't */

    switch(str[curs]) {
      case '%': {
        /* local variables */
        int lowbyte, highbyte;

        curs++; /* skip "%" char */
        highbyte = str[curs] < 65 ? str[curs] - 48 : (str[curs] & 0xdf) - 55;
        curs++;
        lowbyte = str[curs] < 65 ? str[curs] - 48 : (str[curs] & 0xdf) - 55;

        tmp[0] = (highbite * 16) | lowbyte;
        break;
      }
      default: {
        tmp[0] = str[curs];
      }
    }

    strcat(rstr, tmp);

    curs++;
  }
  *base = 0;

  return rstr;
}
--//--

A few notes:

1. in C, strings are but "zero-based" array of chars; we initialize then specifying their length ("char str[XXX]"), and access their i'th char as "str[i]", whith i in [0..strlen(str)-1];

2. i need the "tmp" var plus the strcat() function in order to _only_ append the new parsed character to "rstr"; the code is odd, but please just focus on the algorithm;

3. the "exp0 ? exp1 : exp2" construct gives back:
exp1 if exp0 is true;
exp2 if exp0 is false;

4. operators:
"&" bitwise and;
"|" bitwise or;

5. while this is an external function, you are of course allowed to put "inline" an equivalent code.


The algorithm, as you can see, works basically this way:

1. initialize an empty nstr;
2. parse the given "str" one character at a time;
3. if current char is "%" then;
3.1. read next char (skipping the "%" char); it holds the high-order hexadecimal cypher of an ascii val;
3.2. read next char; it holds the low-order hexadecimal cypher;
3.3. calculate the resulting ascii value to have the unescaped char;
4. whichever the char (normal or just unescaped), append it to nstr;


HTH, anyway let me know if and where you encounter problems.

0
 
LVL 5

Expert Comment

by:julio011597
ID: 1832091
The sorting program:

to give you even a scheme is quite complicated; the point is that C has a built-in QuickSort, which solves most of the problems, so i would just:

1. read the file in memory (i guess you have enough RAM to handle few hundred records);
2. sort the in-memory records through QuickSort;
3. write back results to the file (i.e., overwrite the old version).

If HTMLScript lacks any sorting capability, i could give you a QuickSort routine written in pseudo-C.

Anyway, tell me something on how things are going... i'm a bit lost on what goal i'm expected to reach to make you consider the question answered.
0
 

Author Comment

by:Begemot
ID: 1832092
there isn't a capability that HTMLScript doesn't lack :)

ok lets do this, just write a simple C program that would sort the file, preferably for Win95, but I don't really care, and will call that the answer.  It doesn't really matter how or where I do it, I just need to be able to sort that kind of file efficiently.  Oh, don't read it into RAM I am expecting it could get quite large, over 2500 records.

thanks
0
 
LVL 3

Expert Comment

by:slok
ID: 1832093
It seems that HTMLScript is similiar to Cold Fusion.
They are highler level than C or C++.

Rather good to develope something quick
0
 

Author Comment

by:Begemot
ID: 1832094
much, MUCH  higher level :)
and the price for that speed is of course flexibility.
0
 
LVL 3

Expert Comment

by:slok
ID: 1832095
I'm thinking along this line.
Why not store the data in a simple Access database.
It will sort for you and does not cost a lot.
I'm sure HTMLScript will have some kind of support for ODBC.

Pardon me if I'm wrong cos I'm looking from a Cold Fusion perspective.
0
 

Author Comment

by:Begemot
ID: 1832096
Miva (version 3.0) does, but my host does not support it yet; and I can't use access for two reasons, One I don't have it, and two it doesn't really suit my needs; I don't know much about Access databases but I am pretty sure that it is not what I need
0
 
LVL 5

Expert Comment

by:julio011597
ID: 1832097
Even if each record requires 1K in memory, 2500 records would need 2.5M, which is not very much on today machines.

Anyway, if you still don't want an in-memory solution, i'll write something that sorts on disk.
0
 

Author Comment

by:Begemot
ID: 1832098
ok, do it anyway you see fit :)
0
 
LVL 5

Accepted Solution

by:
julio011597 earned 200 total points
ID: 1832099
Hi back Begemot,

i'm sorry this has taken so long, but i've tried, again, to write something both "readable" and working... what a mess!

So, finally, have decided to give you a "real" C code (you could use it as is), and leave up to you asking for particular clarifications.

--//--
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define SEP '|'      /* field separator definition */

#define MAX_REC 4096  /* max number of records allowed */
#define MAX_STR 128   /* max number of chars allowed in a string + 1 */

typedef struct {  /* record type definition */
  char str1[MAX_STR], str2[MAX_STR];
  int num;
} record;

static record recArray[MAX_REC];  /* array of records */


/* prototype of custom compare function */
static int compare(const void *, const void *);


/* the code */

int main(int argc, char **argv)
{
  register size_t i, num_of_rec;
  char buff[BUFSIZ];
  char *infile_name, *outfile_name;
  FILE *infile, *outfile;

  /* command line parameters parsing */
  if(argc != 3) {
    fputs("Usage: sort <input_file> <output_file>\n", stderr);
    fputs("input_file : input file path name\n", stderr);
    fputs("output_file: output file path name\n", stderr);
    return EXIT_FAILURE;
  }
  infile_name = *(argv + 1);
  outfile_name = *(argv + 2);

  /* read phase */
  if(!(infile = fopen(infile_name, "r"))) {
    perror("Sort: cannot open infile");
    return EXIT_FAILURE;
  }
  for(num_of_rec=0; fgets(buff, BUFSIZ, infile);) {
    register char *curs, *base;

    /* str1: read char by char until SEP or EndOfLine (EOL) */
    i = 0;
    base = recArray[num_of_rec].str1;
    for(curs=buff; *curs && *curs != SEP; curs++) {
      *(base++) = *curs;
      if(++i == MAX_STR-1) {
        for(; *curs && *curs != SEP; curs++);
        break;
      }
    }
    *base = 0;

    /* EOL? (bad input! let's stop) */
    if(!*curs) {
      recArray[num_of_rec].num = 0;
      *(recArray[num_of_rec].str2) = 0;
      break;
    }

    /* num: scan number, then reach next SEP or EOL */
    *(curs++) = 0;
    sscanf(curs, "%d", &(recArray[num_of_rec].num));
    for(; *curs && *curs != SEP; curs++);

    /* EOL? (bad input! let's stop) */
    if(!*curs) {
      *(recArray[num_of_rec].str2) = 0;
      break;
    }

    /* str2: read char by char until '\n' or EndOfLine (EOL) */
    *(curs++) = 0;
    i = 0;
    base = recArray[num_of_rec].str2;
    for(; *curs && *curs != '\n'; curs++) {
      *(base++) = *curs;
      if(++i == MAX_STR-1) break;
    }
    *base = 0;

    /* array full? */
    if(++num_of_rec == MAX_REC) break;
  }
  fclose(infile);

  /* sort phase: quicksort recArray based on our compare() function */
  qsort(recArray, num_of_rec, sizeof(record), compare);

  /* write phase */
  if(!(outfile = fopen(outfile_name, "w"))) {
    perror("Sort: cannot open outfile");
    return EXIT_FAILURE;
  }
  for(i=0; i<num_of_rec; i++)
    fprintf(outfile, "%s|%d|%s\n",
      recArray[i].str1,
      recArray[i].num,
      recArray[i].str2
    );
  fclose(outfile);

  return EXIT_SUCCESS;
}


/* compare based on field "str2" of record */
static int
compare(const void *rec1, const void *rec2)
{
  return strcmp(((record *)rec1)->str2, ((record *)rec2)->str2);
}
--//--

I really hope this is what you were waiting for, because, any way, we have both spent quite a while on it :)


BTW, i could have set up a dynamic array of records, instead of one of fixed lenght, likewise i could have allocated str1 and str2 on the fly, instead of assigning max string length allowed.

Making those changes would have the following consequences:
negatives: code a bit slower;
positives: memory consumption just as needed, unlimited number of records and unlimited length of strings.

But that would have given birth to a more complex code, so i decided to first wait for your feedback.


Regards, julio.
0
 

Author Comment

by:Begemot
ID: 1832100
ok thanks, I have a bit of experience with C/C++ (so I haven't done anything in a while) so I should be alright.  If I have any quesitons I'll tell you.

thanks again,
Dmitrij
0
 
LVL 5

Expert Comment

by:julio011597
ID: 1832101
Thank you for the points.
0

Featured Post

Enroll in May's Course of the Month

May’s Course of the Month is now available! Experts Exchange’s Premium Members and Team Accounts have access to a complimentary course each month as part of their membership—an extra way to increase training and boost professional development.

Question has a verified solution.

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

Suggested Solutions

This article will show, step by step, how to integrate R code into a R Sweave document
A quick Powershell script I wrote to find old program installations and check versions of a specific file across the network.
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

752 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