/* averages.c * program to compute average cost per gallon and miles per gallon from * Superbase exported autolog file * By Joel Swank 8/30/88 * Version 1.1 */ /* Reads a datafile of gasoline purchases of the following format: Individual fields separated by commas. * date - character format (MMM DD YYYY) * odometer reading - 999999.9 * price per gallon - $9.999 * Total cost of purchase - $9999.99 * gallons - 999.9 * place and brand of gas - character Execute from cli. >averages -? ; to get options list */ #include #include #include #include #define STDIN 0 /* file descriptor for stdin */ char linebuf[100]; /* year selection criteria */ int yr = -1; int eyr = -1; int syr = -1; /* Min and Max saveareas */ float maxtank; float maxcost = 0; float maxpr = 0; float maxgal = 0; float minpr =1e10; char maxtdate[20]; char maxprdate[20]; char minprdate[20]; char maxcostdate[20]; char maxgaldate[20]; int maxflag = FALSE; FILE *fdopen(); int fileflag = FALSE; char date[20]; /***********************************************/ /* /* Main routine /* /***********************************************/ main(argc,argv) int argc; char *argv[]; { FILE *filep; int cnt; if (argc == 0) exit(0); /* can't handle workbench */ /* get command line options */ getcmd(argc, argv); /* get command line filenames */ for (cnt=1; cnt < argc; cnt++) { if (*argv[cnt] != '-') { if ((filep = fopen(argv[cnt], "r")) == NULL) fatal("can't open %s", argv[cnt]) ; printf("FILE: %s\n",argv[cnt]); dofile(filep); fclose(filep); fileflag = TRUE; } } if (!fileflag) /* if no files given, use stdin */ { filep = fdopen(STDIN, "r"); dofile(filep); fclose(filep); } } /***********************************************/ /* /* do a file /* /***********************************************/ dofile(fp) FILE *fp; { char *pp, *tp; float firstod = 0, miles, od, atof(); float lastod, prevod; float gallons, cost, price; float totgal = 0, totcost = 0; int count = 0; int year; maxtank = 0; maxcost = 0; maxpr = 0; maxgal = 0; minpr =1e10; while (NULL != fgets(linebuf,100,fp)) { pp = linebuf; tp = date; while (*(pp) != ',') *tp++ = *pp++; /* save date */ *tp ='\0'; pp -= 4; year = atoi(pp); /* get year */ pp += 5; /* eliminate undesired years */ if (yr != -1) { if (year < yr) continue; if (year != yr) break; } if (eyr != -1) { if (year > eyr) break; } if (syr != -1) { if (year < syr) continue; } od = atof(pp); /* get odometer reading */ if (!firstod) firstod = od; else { float t = od-prevod; if (t > maxtank) { maxtank = t; strcpy(maxtdate,date); } } lastod = od; while (*(++pp) != ',') ; while (*(++pp) != '$') ; pp++; price = atof(pp); /* get price */ while (*(++pp) != ',') ; while (*(++pp) != '$') ; pp++; cost = atof(pp); /* get cost */ gallons = cost/price; /* accumulate data */ if (count != 0) { totgal += gallons; totcost += cost; } if (maxflag) { if (price > maxpr) { maxpr = price; strcpy(maxprdate,date); } if (price < minpr) { minpr = price; strcpy(minprdate,date); } if (gallons > maxgal) { maxgal = gallons; strcpy(maxgaldate,date); } if (cost > maxcost) { maxcost = cost; strcpy(maxcostdate,date); } } count++; prevod = od; } /* check for enuf data */ if (count < 2) { printf("No Data\n"); return; } /* print results */ miles = lastod-firstod; printf("%d transactions processed\n", count); if (maxflag) { printf("Maximum distance between transactions= %-5.1f miles on %s\n", maxtank, maxtdate); printf("Maximum gallons = %-5.1f on %s\n", maxgal, maxgaldate); printf("Maximum cost = $%-6.2f on %s\n", maxcost, maxcostdate); printf("Maximum gasoline price = $%-6.3f on %s\n", maxpr, maxprdate); printf("Minimum gasoline price = $%-6.3f on %s\n", minpr, minprdate); } printf("Total Miles = %-8.1f\n", miles); printf("Total Gallons = %-7.1f\n", totgal); printf("Total Cost = $%-8.2f\n", totcost); printf("Average Cost per Gallon = $%-6.4f\n", totcost/totgal); printf("Average Miles per Gallon = %-5.2f\n", miles/totgal); printf("Average Cost per Mile = %-5.2f cents\n", totcost/miles*100); } /***********************************************/ /* /* getcmd - get arguments from command line /* /***********************************************/ getcmd(argc, argv) register argc ; register char *argv[] ; { register cnt ; /* get command options */ for (cnt=1; cnt < argc; cnt++) { if (*argv[cnt] == '-') { switch(argv[cnt][1]) { case 's': syr = val_yr(&argv[cnt][2]) ; if (syr == -1) fatal("Bad -s value: %s", argv[cnt]) ; printf("Starting with data for year %4d\n",syr); break ; case 'e': eyr = val_yr(&argv[cnt][2]) ; if (eyr == -1) fatal("Bad -e value: %s", argv[cnt]) ; printf("Eending with data for year %4d\n",eyr); break ; case 'y': yr = val_yr(&argv[cnt][2]) ; if (yr == -1) fatal("Bad -y value: %s", argv[cnt]) ; printf("Extracting data for year %4d\n",yr); break ; case 'm': maxflag = TRUE; break ; case '?': /* help option */ usage(); printf(" averages Ver 1.1 - calculate auto averages.\n"); printf(" Options:\n"); printf(" ynn - for requested year only.\n"); printf(" snn - year to start.\n"); printf(" enn - year to end.\n"); printf(" m - include max and min information.\n"); printf(" ? - display this list.\n"); exit(0); default: usage(); exit(0); } } } } usage() { printf("usage:averages [-snn] [-enn] [-ynn] [-m] [-?] [file ...]\n"); } /* * fatal - print standard error msg and halt process */ fatal(ptrn, data1, data2) register char *ptrn, *data1, *data2 ; { printf("ERROR: "); printf(ptrn, data1, data2) ; putchar('\n'); exit(1); } /* * val_yr : validate a year string gadget contents and return * -1 if invalid or year if valid. */ val_yr(buffer) char *buffer; { int yr; char *bufp; bufp = buffer; while (*bufp != '\0') { if (!isdigit(*bufp)) return -1; bufp++; } yr = atoi(buffer); if (yr <100 && yr >= 0) return yr+1900; if (yr <2200 && yr >= 1900) return yr; return -1; }