/* Convert floating field formatted data files to fixed field [] - Determined at task-build/install time (Try FFF). - The ASCII data file to be reformatted. - The file to receive the reformatted ASCII data. The default is to use the same name as the input file. The input file is assumed to contain records of ASCII data in floating format (i.e. variable length) fields. Each field is delimited by one or more white_space characters. Note: Null fields delimited by a comma are not ignored. For example, in the record: "123, , 456, 789" The first field contains "123", the second field contains "", the third field contains "456", and the fourth field contains "789". Each field must be "occupied" by at least one data character and/or a comma. Input records with fewer fields than the maximum number of fields per record found in the file will have blank (space-filled) fields appended to the output record. Thus all output records will be the same length. */ #include #include #include #define MAX_CHARACTERS 1000 TEXT record[MAX_CHARACTERS]; INTEGER field[MAX_CHARACTERS >> 1]; INTEGER fields = 0; GLOBAL STRING white_space; LOCAL STRING start_field (end) STRING end; { /* It is assumed that "end" is pointing to the end of the previous field (i.e. the first delimiter after field data characters), and we want to find the start of the next field's data characters (i.e. skip over delimiters). If the end-of-field is delimited by a comma, move the end pointer to the next character in the string before skipping white_space. The white_space characters do not include the comma. */ if (*end == ',') end++; white_space = " \t"; return (skip_white (end)); } LOCAL STRING end_field (start) STRING start; { /* It is assumed that "start" is pointing to the start of the previous field (i.e. the first data character of the field), and we want to find the end of the field's data characters (i.e. the first delimiter after the data characters; skip non-white_space characters). The delimiters include the comma. */ white_space = " \t,"; return (skip_n_white (start)); } main (count, argument) INTEGER count; STRING argument[]; { REGISTER STRING start; REGISTER STRING end; REGISTER amount; INTEGER number; FILE *input; FILE *output; /* Get the input filename (start) and output filename (end). */ if (count == 1) { if (!(printf ("Input file: "), gets (start = &record)) || !strlen (start)) exit (); if (!(printf ("Output file: "), gets (end = &record[MAX_CHARACTERS >> 1]))) exit (); else if (!strlen (end)) end = start; } else { start = argument[1]; if (count > 2) end = argument[2]; else end = start; } /* Open the input and output files. */ if (! (input = fopen (start, "r"))) { printf ("Unable to open input file %s\n%s\n", start, ioerrmsg (IO_ERROR)); exit (); } if (! (output = fopen (end, "w"))) { printf ("Unable to open output file %s\n%s\n", end, ioerrmsg (IO_ERROR)); exit (); } /* Scan each record of the input file. */ while (fgetss (record, MAX_CHARACTERS, input)) { /* Measure the length of each field in the record, and keep a running maximum length value for each sequential field in a record, and the maximum number of fields in all records. */ for ( count = 0, start = start_field (record), end = end_field (start); *start; count++, start = start_field (end), end = end_field (start) ) if (field[count] < (amount = end - start)) field[count] = amount; if (fields < count) fields = count; } if (fields) { /* List the output record format. */ printf ("\n%d fields per record -\n 1(@ 1): %3d\n", fields, field[0]); for ( count = 1, number = field[0] + 1; count < fields; number += field[count++] ) printf ("%3d(@%3d): %3d\n", count + 1, number, ++field[count]); printf ("%d characters per record.\n", --number); rewind (input); /* Reformat all file records. */ for (number = 0; fgetss (record, MAX_CHARACTERS, input); number++) { for ( count = 0, start = start_field (record), end = end_field (start); *start; count++, start = start_field (end), end = end_field (start) ) { if (*start == ',') { *start = ' '; amount = 1; } else amount = end - start; fprintf (output, "%*.*s", field[count], amount, start); } for (;count < fields; count++) fprintf (output, "%*s", field[count], " "); fprintf (output, "\n"); } printf ("%d records output.\n", number); } else printf ("No data fields!\n"); fclose (input); fclose (output); }