griffin@prism.gatech.EDU (GRIFFIN,JEFFREY A) (06/27/91)
HELP! from a C guru urgently needed and appreciated. I am looking for suggestions for reading a data file of which two records are listed below. Each record consists of 512 characters plus a new-line. There is an initial byte count of 0133 then 32 integer values, another byte count of 0133 and 32 integers, the last byte count of 0133 and the last 32 integers. The remainder of the record is padded with the '^' character. The read would certainly be more trivial if the last integer in each group was followed by a space before the next byte count. In FORTRAN I would read this as 3(I5, 32(I4)). I would like to read each record into a buffer string and then process the record. In this way I can keep better track of where I am in the file and track any possible alignment errors when trying to read the file. (1) What would be the best way to handle this? (2) Has anyone written any I/O routines that are similar to doing formatted reads in FORTRAN? For example a read command that supports the grouping of numbers i.e. 32%5d, etc. 0133 45 46 46 44 45 46 46 46 46 46 47 46 44 45 45 45 47 46 45 46 46 45 45 46 46 47 46 46 46 46 46 460133 46 46 46 46 46 47 47 47 47 47 47 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 47 46 47 48 47 470133 46 45 45 47 47 47 47 47 47 47 47 47 46 46 48 47 47 47 46 45 47 47 46 47 47 46 46 47 46 46 46 45^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0133 46 47 47 47 47 46 46 47 47 47 47 47 48 47 47 46 46 46 47 47 46 47 47 45 46 46 46 46 46 46 47 460133 46 48 47 47 47 46 47 48 46 47 46 45 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 46 46 46 45 470133 48 48 48 46 47 47 46 47 47 47 47 47 46 47 47 46 47 47 46 47 47 45 46 47 47 47 47 46 47 47 45 47^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Griffin, Jeffrey A. Georgia Institute of Technology, Atlanta Georgia, 30332 uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!griffin Internet: griffin@prism.gatech.edu
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (06/27/91)
In article <31839@hydra.gatech.EDU>, griffin@prism.gatech.EDU (GRIFFIN,JEFFREY A) writes: > I am looking for suggestions for reading a data file of which two > records are listed below. Each record consists of 512 characters > plus a new-line. There is an initial byte count of 0133 then 32 > integer values, another byte count of 0133 and 32 integers, the > last byte count of 0133 and the last 32 integers. The remainder of > the record is padded with the '^' character. What you have here is ANSI format for a tape with variable-length records stored in 512-byte blocks. The new-line is probably someone trying to be helpful. I suggest attacking this in two stages. Stage 1: break the file into records. int read_Record(FILE *f, char *buffer) /* returns EOF */ { /* or strlen(buffer) */ int c; /* EOF also means "error" */ /* We should be at the beginning of a record. */ /* Padding ^ characters and extra new-lines may intervene. */ do { do c = getc(f); while (c == '^'); } while (c == '\n'); /* By now, only EOF and <four decimal digits> are ok. */ if (c == EOF) return EOF; /* real EOF; others=error */ ungetc(c, f); if (fscanf(f, "%4d", &c) != 1 || c <= 0) return EOF; if (fread(buffer, 1, c, f) != c) return EOF; buffer[c] = '\0'; return c; } Stage 2: parse the records using sscanf(), or, perhaps easier in this case, strtol(). -- I agree with Jim Giles about many of the deficiencies of present UNIX.