/* ** fileio.c */ #include #include "peek.h" /* ** get_source() ** gets source of input for object info, either from file, in which case ** it returns a file pointer, or from stdin, in which case it returns ** NULL. ** pesters user until a valid filename is given. */ FILE * get_source() { FILE *file; char filename[32]; int c; do { printf("name of file to read from? "); scanf("%s", filename); file = fopen(filename, "r"); } while(NULL == file); return (file); } /* ** get_output() ** returns file pointer of file that something is to be saved to ** won't quit pestering user until a valid filename is put it. */ FILE * get_output(char *s) { FILE *file; char filename[32]; int c; do { printf("name of file to write %s to? ", s); scanf("%s", filename); file = fopen(filename, "w"); } while(NULL == file); return(file); } /* ** skip() ** reads past all comments and whitespace, leaving file pointer on first ** thing that is not comment or whitespace. Returns EOF if hits EOF in ** process of looking. */ int skip(FILE *file) { static char whites[5] = {' ', '\t', '\n', '\r', '\0'}; char c; int done = 0; while (!done) { while (strchr(whites, (c=fgetc(file)))); if (EOF == c) { return(EOF); } fseek(file, -1, SEEK_CUR); /* we got to character past all whites */ if (COMMCH == (c=fgetc(file))) { while ('\n' != (c=fgetc(file))) { if (EOF == c) { return(EOF); } } } else { done = 1; fseek(file, -1, SEEK_CUR); /* we had to read this character to see if it was COMMCH */ } } return(0); } /* ** get_int() ** gets an integer from file, reading past comments (beginning with COMMCH) ** if there is some error, returns EOF; returns ENDLIST if it hits a ENDLCH. */ int get_int(FILE *file, int *d) { char c, intstr[MAXINTLEN], valid_int_str[12] = {'-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\0'}; int i = 0, num; if (EOF == skip(file)) { sprintf(err, "get_float: Couldn't skip\n"); return(EOF); } if (ENDLCH == (c=getc(file))) { return(ENDLIST); } else fseek(file, -1, SEEK_CUR); while (strchr(valid_int_str, (c=getc(file)))) { if (i < MAXINTLEN - 1) { intstr[i++] = c; } else { intstr[i++] = 0; sprintf(err, "get_int: Int string |%s| too long\n", intstr); return(EOF); } } fseek(file, -1, SEEK_CUR); intstr[i++] = '\0'; if (EOF == sscanf(intstr, "%d", &num)) { sprintf(err, "get_int: Invalid integer format encountered\n"); return(EOF); } *d = num; return(0); } /* ** get_float() ** gets a float from file, reading past comments (beginning with COMMCH) ** if there is some error, returns EOF; returns ENDLIST if it hits a ENDLCH. */ int get_float(FILE *file, float *f) { char c, floatstr[MAXFLOATLEN], valid_float_str[13] = {'-', '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\0'}; int i = 0; float num; if (EOF == skip(file)) { sprintf(err, "get_float: Couldn't skip\n"); return(EOF); } if (ENDLCH == (c=getc(file))) { return(ENDLIST); } else fseek(file, -1, SEEK_CUR); while (strchr(valid_float_str, (c=getc(file)))) { if (i < MAXFLOATLEN - 1) { floatstr[i++] = c; } else { floatstr[i++] = 0; sprintf(err, "get_float: float string %s too long\n", floatstr); return(EOF); } } fseek(file, -1, SEEK_CUR); floatstr[i++] = '\0'; if (EOF == sscanf(floatstr, "%g", &num)) { sprintf(err, "get_float: Invalid float format %s encountered\n", floatstr); return(EOF); } *f = num; return(0); } /* ** next_sect() ** reads past everything to next SECTCH in file, leaves file pointer on character ** following SECTCH. If it hits EOF, returns -1. */ int next_sect(FILE *file) { char c; while(SECTCH != (c=fgetc(file))); if (EOF == c) { sprintf(err, "next_sect: encountered EOF when looking for next section\n"); return(-1); } return(0); }