Mega Code Archive

 
Categories / C / Small Application
 

Sort text data by soundex value

#include <stdio.h> #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 < min_len || 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); }