Mega Code Archive

 
Categories / C / Small Application
 

Sort text data by rhyming order

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <getopt.h> #define PACKAGE "rhymsort" #define VERSION "0.0.2" #define MAXLINE 1024 struct lnode { char *str; struct lnode *next; }; struct lnode *insert(char *data, struct lnode *list); void free_list(struct lnode *list); void print_list(struct lnode *list, int r); void rev(char *str); 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 len = 0; /* initial line length */ int opt = 0; /* holds getopt option nr ... */ int min_len = 2; /* minimumn accepted length of incomming lines */ int out_rev_flag = 0; /* output the `raw' reversed lines */ int strip_nl_flag = 0; /* strip trailing newlines from input */ while((opt = getopt(argc, argv, "hvrsn:f:")) != -1) { switch(opt) { case 'h': print_help(0); break; case 'v': exit(0); break; case 'r': out_rev_flag = 1; break; case 's': strip_nl_flag = 1; break; case 'n': min_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) continue; /* strip trailing newlines */ if(strip_nl_flag == 1 && line[len - 1] == '\n') line[len - 1] = '\0'; /* reverse line[] buffer */ rev(line); /* insert line in the linked list */ list = insert(line, list); } print_list(list, out_rev_flag); free_list(list); fclose(fp); return 0; } struct lnode *insert(char *data, 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); /* first, we handle the case where `data' should be the first element */ if(list == NULL || strcmp(list->str, data) > 0) { /* 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 && strcmp(q->next->str, data) < 0) { 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); list = p; } } void print_list(struct lnode *list, int r) { struct lnode *p; for(p = list; p != NULL; p = p->next) if(r == 0) rev(p->str), printf("%s\n", p->str); else printf("%s\n", p->str); } /* reverse string ... */ void rev(char *str) { char temp = 0; char *end = NULL; /* point to last non-NULL character in str */ end = str + strlen(str) - 1; while(str < end) temp = *str, *str++ = *end, *end-- = temp; } void print_help(int exval) { printf("%s,%s sort text data by rhyming order\n", PACKAGE, VERSION); printf("Usage: %s [-h] [-v] [-r] [-s] [-n INT] [-f FILE]\n\n", PACKAGE); printf(" -h print this help and exit\n"); printf(" -v print version and exit\n\n"); printf(" -r output the `raw' reversed lines\n"); printf(" -s strip trailing newlines\n"); printf(" -n INT ignore lines shorter as `INT' (default=2)\n"); printf(" -f FILE read input from `FILE' (default=stdin)\n\n"); exit(exval); }