/* * Quick and dirty to extract selected fields from a (mostly) comma * delimited file for uploading to mainframe. The names of input, * output, and format files may be specified in any order. * * Written by Warren Porter, CDP 10/07/95 09:11 am */ typedef struct { /* Define table */ int no_reads, field_len; char field_type; } tab_type; #include #include FILE *ip,*op; int working=1, bwdisp=0; void read_field(char *apnt); void write_field(char *apnt, int len, char type); int main(int argc, char *argv[]) { int i, j, rec_cnt=0, edit_byte=0, tab_size=0; char achar, buff[100], *infile, *outfile, *fmtfile, *cobfile=NULL; tab_type *table=NULL, *pnt; FILE *fmt; argv++; while (argc > 1) { if (argv[0][0] != '-') { fprintf(stderr,"Expecting - found %c\a\n",argv[0][0]); exit(1); } switch (argv[0][1]) { case 'i': case 'I': case 'r': case 'R': { argc--; argv++; infile=*argv; edit_byte |= 1; argc--; argv++; break; } case 'o': case 'O': { argc--; argv++; outfile=*argv; edit_byte |= 2; argc--; argv++; break; } case 'F': case 'f': { argc--; argv++; fmtfile=*argv; edit_byte |= 4; argc--; argv++; break; } case 'c': case 'C': { argc--; argv++; cobfile=*argv; argc--; argv++; break; } case 'm': case 'M': { bwdisp=1; argc--; argv++; break; } default: fprintf(stderr,"Unexpected character in parameter %c\a\n", argv[0][1]); exit(1); } /* End of switch */ } /* End of while for checking paramters */ if (edit_byte != 7) { printf("Three command line arguments are required -i -o & -f\n"); printf("Names of input, output, and format can be in any order\n"); printf("Other options: -c filename for COBOL layout "); printf("and -m for error messages \n (field truncated)\n\n"); printf("Contents of format file:\n"); printf("Number of fields to read (1 to read next field "); printf("5 would skip 4 fields\n"); printf("Comma delimiter\n"); printf("Field length\n"); printf("Comma delimiter\n"); printf("Character 'n' for numeric or 'a' for alphabetic\n"); printf("Comments if desired\n\n"); printf("Example: 1, 9,n Use first or next field 9(9)\n"); printf(" 8,15,a Skip 7 fields to get to X(15)\n"); exit(1); } if ( (fmt = fopen(fmtfile,"r")) == NULL ) { fprintf(stderr,"Couldn't open %s\a",fmtfile); exit(1); } while (1) { /* Read the format file */ if ( (fgets(buff,99,fmt)) == NULL) /* Exit at end of file */ break; tab_size++; table=(tab_type *)realloc(table,sizeof(tab_type)*tab_size); if (!table) { fprintf(stderr,"Could not allocate memory for %d\a",tab_size); exit(1); } pnt = &table[tab_size - 1]; j=0; for (i=0;buff[i] != ',';i++) if (isdigit(buff[i])) j = j*10 + (buff[i] - '0'); pnt->no_reads = j; j=0,i++; for (;buff[i] != ',';i++) if (isdigit(buff[i])) j = j*10 + (buff[i] - '0'); pnt->field_len = j; pnt->field_type = tolower(buff[i+1]); } fclose(fmt); if ( (ip = fopen(infile,"rb")) == NULL ) { fprintf(stderr,"Couldn't open %s\a",infile); exit(1); } if ( (op = fopen(outfile,"wb")) == NULL ) { fprintf(stderr,"Couldn't open %s\a",outfile); exit(1); } while (working) { for (j=0;j < tab_size;j++) { /* To select fields */ pnt = &table[j]; for (i=0;i < pnt->no_reads;i++) read_field(buff); if (!working) break; write_field(buff,pnt->field_len,pnt->field_type); } if (working) { /* Put cr-lf on the end */ putc(13,op); putc(10,op); rec_cnt++; } do { achar=getc(ip); /* Read next char before loop */ if (feof(ip)) { /* to flush to end of record on ip */ working=0; break; } } while (achar >= ' '); if (working) { while (achar < ' ') { achar=getc(ip); /* To get past cr/lf combo */ if (feof(ip)) { working=0; break; } } ungetc(achar,ip); /* Ready for next record */ } if (!(rec_cnt % 50)) printf("%d written so far\n\n",rec_cnt); } fprintf(stderr,"%d records written\n",rec_cnt); j=0; for (i=0;i < tab_size;i++) j += table[i].field_len; fprintf(stderr,"The record length will be %i.\n",j); fclose(ip); fclose(op); if (cobfile == NULL) /*No record layout requested */ exit(0); if ( (op = fopen(cobfile,"w")) == NULL ) { fprintf(stderr,"Couldn't open %s\a",cobfile); exit(1); } fprintf(op," 01 REC-LAYOUT.\n"); for (i=0;i < tab_size;i++) fprintf(op," 02 FIELD%02d PIC %c(%02d).\n", i+1,(table[i].field_type == 'n')?'9':'X',table[i].field_len); fclose(op); } void read_field(char *apnt) { int i; char delim, achar; delim=','; /* Set delimiter initially to comma */ achar=getc(ip); /* Read first character */ if (feof(ip)) { working=0; return; } if (achar == '"') /* If it was a quote, set the delimiter*/ delim = achar; else if (achar == ',') { *apnt=0; return; } else { *apnt = achar; /* Else copy 1st character in and bump point*/ apnt++; } achar=getc(ip); /* Read next char before loop */ if (feof(ip)) { working=0; return; } for ( ; (achar != delim) ; apnt++) { /* Copy to buffer and */ *apnt=achar; /* get next char until */ achar=getc(ip); /* delimiter found */ if (feof(ip)) { working=0; return; } } *apnt=0; /* So will be null terminated */ if (delim == '"') /* If a quote, get past it */ getc(ip); } void write_field(char *apnt, int len, char type) { int i, len_string, diff; len_string = strlen(apnt); if (len_string > len) { if (bwdisp) printf("Field length of %d specified, %d found\n", len, len_string); len_string = len; apnt[len] = 0; } if (type == 'n') for (diff = len - len_string;diff;diff--) putc('0',op); for ( ; *apnt >= ' '; apnt++) putc(*apnt,op); if (type != 'n') for (diff = len - len_string;diff;diff--) putc(' ',op); }