Wednesday 25 August 2010

Pick and print a random value, line in c

Pick and print a random value, line

#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>

#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);
}

Read more: http://cmagical.blogspot.com/2010_02_14_archive.html#ixzz0xgYrBHLI

No comments:

Post a Comment