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

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.
BegemotAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

julio011597Commented:
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
BegemotAuthor Commented:
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
julio011597Commented:
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
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

BegemotAuthor Commented:
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
julio011597Commented:
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
julio011597Commented:
Sorry, rereading your question, i see you talk about hundreds of lines: that's enough to know.

Just waiting for the target OS.
0
BegemotAuthor Commented:
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
julio011597Commented:
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
julio011597Commented:
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
BegemotAuthor Commented:
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
slokCommented:
It seems that HTMLScript is similiar to Cold Fusion.
They are highler level than C or C++.

Rather good to develope something quick
0
BegemotAuthor Commented:
much, MUCH  higher level :)
and the price for that speed is of course flexibility.
0
slokCommented:
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
BegemotAuthor Commented:
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
julio011597Commented:
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
BegemotAuthor Commented:
ok, do it anyway you see fit :)
0
julio011597Commented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BegemotAuthor Commented:
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
julio011597Commented:
Thank you for the points.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Scripting Languages

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.