Mega Code Archive

 
Categories / C / Small Application
 

Pick and print a random value, line

#include <time.h> #include <stdio.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <getopt.h> #include <limits.h> #include <sys/stat.h> #include <sys/types.h> #define PACKAGE "pand" #define VERSION "0.0.3" #define MAXLINE 1024 /* status epilepticus, print help and exit with `exval' */ void print_help(int exval); /* picks a radom value withing range low-high*/ int get_rand_val(int low, int high); /* ! definitely not cryptographic secure ! */ /* value returned seeds the rand() function */ unsigned time_seed(void); int main(int argc, char *argv[]) { int i = 0; /* generic counter */ int len = 0; /* line length */ int opt = 0; /* holds the parsed option nr */ int pick = 0; /* holds the random pick number */ int exval = 0; /* exit code for program */ int verbose = 0; /* work verbose ... */ int outputnum = 1; /* number of random lines to output, default = 1 */ int linecount = 0; /* line counter */ int maxlsize = -1; /* do not include lines shorter as maxlsize */ FILE *fp = NULL; /* filestream pointer */ char line[MAXLINE]; /* line buffer */ char **strarray = NULL; /* the string array which holds all the lines */ /* no options given ? */ if(argc == 1) print_help(0); while((opt = getopt(argc, argv, "hVvl:n:")) != -1) { switch(opt) { case 'h': /* status epilepticus, print help and exit with `exval' */ print_help(0); break; case 'V': /* print version information and exit */ exit(0); break; case 'v': verbose = 1; break; case 'l': /* only index lines longer as `maxlsize' */ maxlsize = atoi(optarg); break; case 'n': /* number of random lines to output default = 1 */ outputnum = atoi(optarg); break; case '?': /* unkown option */ fprintf(stderr, "%s: Error - no such option `%c'\n\n", PACKAGE, optopt); print_help(1); break; case ':': /* option requires an argument */ fprintf(stderr, "%s: Error - option `%c' requires an argument\n\n", PACKAGE, optopt); print_help(1); break; } /* switch */ } /* while */ /* no input arguments [files] left ? */ if((argc - optind) == 0) { fprintf(stderr, "%s: Error - No input files given...\n\n", PACKAGE); print_help(1); } /* first seed the random function */ srand((time_seed())); /* loop over all input files */ for(; optind < argc; optind++) { if((fp = fopen(argv[optind], "r")) == NULL) { perror(argv[optind]); exval = 1; continue; } if(verbose == 1) printf("%s: reading file `%s'\n", PACKAGE, argv[optind]); /* read lines */ while((fgets(line, MAXLINE, fp)) != NULL) { len = strlen(line); /* if max size... ignore line */ if(maxlsize != -1 && len < maxlsize) continue; /* strip trailing newline */ if(line[len - 1] == '\n') line[len - 1] = '\0'; /* add the line, to the array of strings */ strarray = (char **)realloc(strarray, (linecount + 1) * sizeof(char *)); strarray[linecount++] = strdup(line); } /* while */ if(verbose == 1) printf("%s: array length now `%d'\n", PACKAGE, linecount); fclose(fp); } /* for */ /* output INT number of lines; (default=1) */ for(; outputnum > 0; outputnum--) { /* is the array actually filled up with entrys ? */ if(linecount <= 1) { exval = 2; break; } else { /* pick a random value */ pick = get_rand_val(1, linecount); /* print the entry */ if(verbose == 1) printf("%s: %2d %s\n", PACKAGE, pick, strarray[pick]); else printf("%s\n", strarray[pick]); } } /* for */ /* free each entry */ for(i = 0; i < linecount; i++) free(strarray[i]); /* free the string array */ free(strarray); if(verbose == 1) { if(exval == 1) printf("%s: Error - exit value `1'\n", PACKAGE); else if(exval == 2) printf("%s: Error - exit value `2', not enough input...\n", PACKAGE); else printf("%s: normal exit value `0'\n", PACKAGE); } return exval; } /* end main */ /* picks a radom value withing range low-high*/ int get_rand_val(int low, int high) { int k = 0; double d = 0; d = (double)rand() / ((double)RAND_MAX + 1); k = (int)(d * (high - low + 1)); return(low + k); } /* ! definitely not cryptographic secure ! */ /* value returned seeds the rand() function */ unsigned time_seed(void) { int retval = 0; int fd; /* just in case open() fails.. */ if(open("/dev/urandom", O_RDONLY) == -1) { retval = (((int)time(NULL)) & ((1 << 30) - 1)) + getpid(); } else { read(fd, &retval, 4); /* positive values only */ retval = abs(retval) + getpid(); close(fd); } return retval; } /* status epilepticus, print help and exit with `exval' */ void print_help(int exval) { printf("%s,%s pick random values from a file\n", PACKAGE, VERSION); printf("Usage: %s [-h] [-V] [-v] [-l INT] [-n INT] FILE1 FILE2...\n\n", PACKAGE); printf(" Options:\n"); printf(" -h print this help and exit\n"); printf(" -V print version and exit\n"); printf(" -v work verbose\n"); printf(" -l INT pick only lines longer as `INT' characters\n"); printf(" -n INT pick `INT' random lines from input (default=1)\n\n"); printf(" Note: %s reads all input into memory first, and\n", PACKAGE); printf(" only then picks a random entry from the memory.\n\n"); exit(exval); }