/* This is the program "csvlookup.c", by Jeffrey Rosenthal. It tries to match column "maincol" of csv file "mainfile" with column "matchcol" of csv file "matchfile", and then append column "newcol" of "matchfile" to the "mainfile" line. It sends the resulting augmented csv file to standard output. (Its functionality may be somewhat similar to the Excel "VLOOKUP" function.) Compile with the command: cc csvlookup.c -o csvlookup Usage: csvlookup mainfile maincol matchfile matchcol newcol */ #include #include #include #include #define verboselevel 2 #define DEFMAXCOL 4 #define MAXFILENAMELENGTH 99 #define MAXMATCHFILELENGTH 9999 /* Global variables for parsing input lines etc. */ #define INPUTFILE "stdin" #define MAXNUMFIELDS 999 #define MAXFIELDLENGTH 999 #define MAXLINELENGTH 9999 #define MAXNUMITEMS 99 #define MAXITEMLENGTH 99 char linedata[MAXNUMFIELDS][MAXFIELDLENGTH]; char theline[MAXLINELENGTH]; char prevline[MAXLINELENGTH]; int totnumfields, filedone, maxnumcourses; /* Other global variables. */ #define MAXNUMSTUD 2000 /* BEGIN MAIN PROGRAM. */ int main(int argc, char **argv) { /* Initial declarations. */ char mainfile[MAXFILENAMELENGTH], matchfile[MAXFILENAMELENGTH]; int maincol, matchcol, newcol; char matchstring[MAXMATCHFILELENGTH][MAXNUMITEMS]; char newstring[MAXMATCHFILELENGTH][MAXNUMITEMS]; int i, nextline(), parseline(); int matchnum = 0; FILE *fp, *fopenit(); // Usage: csvlookup mainfile maincol matchfile matchcol newcol /* Sort out command-line arguments. */ if (argc < 6) { fprintf(stderr, "Error: too few arguments.\n"); exit(1); } strncpy(mainfile, argv[1], MAXFILENAMELENGTH); strncpy(matchfile, argv[3], MAXFILENAMELENGTH); maincol = atoi(argv[2]); matchcol = atoi(argv[4]); newcol = atoi(argv[5]); fp = fopenit(matchfile, "r"); /* Read through matchfile, collecting data. */ filedone = i = 0; while (filedone == 0) { /* Read and process a line of the file. */ nextline(fp); if (filedone==0) { parseline(); strncpy(matchstring[i], linedata[matchcol], MAXITEMLENGTH); strncpy(newstring[i], linedata[newcol], MAXITEMLENGTH); i++; } } matchnum = i; if (verboselevel >= 2) for (i=0; i= MAXNUMFIELDS) { fprintf(stderr, "Error: maximum number of fields exceeded.\n"); exit(1); } fieldlength = 0; } else if ( (theline[linespot]=='\n') || (theline[linespot]=='\0') ) { /* Deal with end of line. */ linedata[fieldnum][fieldlength] = '\0'; fieldnum++; done = 1; } else { /* Deal with ordinary characters. */ linedata[fieldnum][fieldlength] = theline[linespot]; fieldlength++; if (fieldlength >= MAXFIELDLENGTH) { linedata[fieldnum][fieldlength] = '\0'; fprintf(stderr, "Error: field length %d >= %d: %s\n", fieldlength, MAXFIELDLENGTH, linedata[fieldnum]); exit(1); } } linespot++; } totnumfields = fieldnum; if (verboselevel>=2) printf("parseline: totnumfields=%d\n", totnumfields); return(0); } FILE *fopenit(char *thefilename, char *themode) { FILE *thefp; char verb[20]; if (!strcmp(themode,"w")) strcpy(verb,"write"); else if (!strcmp(themode,"r")) strcpy(verb,"read"); else if (!strcmp(themode,"a")) strcpy(verb,"append to"); else strcpy(verb,"access"); if ((thefp = fopen(thefilename,themode)) == NULL) { fprintf(stderr, "\n ** Unable to %s file %s. **\n\n", verb, thefilename); exit(1); } return(thefp); }