#include "ctype.h"
#include "stdlib.h"
#include "string.h"
#include "getopt.h"
#define PACKAGE "sndsort"
#define VERSION "0.0.2"
#define MAXLINE 1024
struct lnode
{
char *str;
int sndval;
struct lnode *next;
};
struct lnode *insert(char *data, int val, struct lnode *list);
char *soundex(char *str);
void free_list(struct lnode *list);
void print_list(struct lnode *list, int x);
void print_help(int exval);
int main(int argc, char *argv[]) {
FILE *fp = stdin; /* read input from... (default is stdin) */
struct lnode *list; /* linked list */
char line[MAXLINE]; /* buff for fgets() */
int sval = 0; /* return value from soundex() */
int len = 0; /* initial line length */
int opt = 0; /* holds getopt option nr ... */
int min_len = 2; /* ignore lines Shorter as length (default=2) */
int max_len = 20; /* ignore lines Longer as length (default=20) */
int out_sndx_flag = 0; /* output the `soundex value' for each string */
int strip_nl_flag = 0; /* strip trailing newlines from input */
while((opt = getopt(argc, argv, "hvxsn:N:f:")) != -1) {
switch(opt) {
case 'h':
print_help(0);
break;
case 'v':
exit(0);
break;
case 'x':
out_sndx_flag = 1;
break;
case 's':
strip_nl_flag = 1;
break;
case 'n':
min_len = atoi(optarg);
break;
case 'N':
max_len = atoi(optarg);
break;
case 'f':
if(freopen(optarg, "r", fp) == NULL) {
fprintf(stderr, "%s: Error - opening `%s'\n", PACKAGE, optarg);
return 1;
}
break;
case ':':
fprintf(stderr, "%s: Error - Option `%c' needs an argument\n\n", PACKAGE, optopt);
print_help(1);
case '?':
fprintf(stderr, "%s: Error - No such option: `%c'\n\n", PACKAGE, optopt);
print_help(1);
} /* switch */
} /* while */
list = NULL;
while((fgets(line, MAXLINE, stdin)) != NULL) {
len = strlen(line);
/* skip lines shorter as ``min_len'' in length */
if(len <> max_len) continue;
/* strip trailing newlines */
if(strip_nl_flag == 1 && line[len - 1] == '\n')
line[len - 1] = '\0';
/* reverse line[] buffer */
sval = atoi(soundex(line));
/* insert line in the linked list */
list = insert(line, sval, list);
}
print_list(list, out_sndx_flag);
free_list(list);
fclose(fp);
return 0;
}
struct lnode *insert(char *data, int sval, struct lnode *list) {
struct lnode *p;
struct lnode *q;
/* create a new node */
p = (struct lnode *)malloc(sizeof(struct lnode));
/* save data into new node */
p->str = strdup(data);
p->sndval = sval;
/* first, we handle the case where `data' should be the first element */
if(list == NULL || list->sndval > sval) {
/* apperently this !IS! the first element */
/* now data should [be|becomes] the first element */
p->next = list;
return p;
} else {
/* search the linked list for the right location */
q = list;
while(q->next != NULL && q->next->sndval < sval) {
q = q->next;
}
p->next = q->next;
q->next = p;
return list;
}
}
void free_list(struct lnode *list) {
struct lnode *p;
while(list != NULL) {
p = list->next;
free(list->str);
free(list);
list = p;
}
}
void print_list(struct lnode *list, int x) {
struct lnode *p;
for(p = list; p != NULL; p = p->next)
if(x == 1)
printf("%8d %s\n", p->sndval, p->str);
else
printf("%s\n", p->str);
}
/* get soundex code for a string */
char *soundex(char *str) {
static char soundexbuf[81];
/*
// basicly ripped this piece of the code straight
// from the book... ehum.. sorry...
*/
char *table = "01230120022455012623010202";
char *sdx = soundexbuf, lastchr = ' ';
while(*str) {
if(isalpha(*str) && (*str != lastchr)) {
*sdx = *(table + toupper(*str) - 'A');
if((*sdx != '0') && (*sdx != lastchr))
lastchr = *sdx++;
}
str++;
}
*sdx = '\0';
return &soundexbuf[0];
}
void print_help(int exval) {
printf("%s,%s sort text data by soundex value\n", PACKAGE, VERSION);
printf("Usage: %s [-h] [-v] [-x] [-s] [-n INT] [-N INT] [-f FILE]\n\n", PACKAGE);
printf(" -h print this help and exit\n");
printf(" -v print version and exit\n\n");
printf(" -x output the `soundex value' with each string\n");
printf(" -s strip trailing newlines\n");
printf(" -n INT ignore lines Shorter as `INT' (default=2)\n");
printf(" -N INT ignore lines Longer as `INT' (default=20)\n");
printf(" -f FILE read input from `FILE' (default=stdin)\n\n");
exit(exval);
}
No comments:
Post a Comment