/* Name: readfile4.c Purpose: Similar to readfile3.c, with a re-implementation of readLine Author: Bill Slough Bugs: 1. We continue to assume no read error will occur. */ #include #include #include #include #define FILE_NAME "words" /* name of the input file */ #define MAX_WORD_LENGTH 8 /* adjust as needed */ char *readLine(char *s, int n, FILE *fp, bool *overflow); int main(void) { FILE *fp; /* file pointer for an input stream */ int lineCount; /* number of lines processed */ bool lineOverflow; /* not enough room in char array? */ int nrErrors; /* how many lines overflow char array? */ char line[MAX_WORD_LENGTH + 1]; /* string to hold one line of input */ /* Try to open the input stream for reading */ fp = fopen(FILE_NAME, "r"); if (fp == NULL) { fprintf(stderr, "Error: can't open %s for reading.\n", FILE_NAME); exit(EXIT_FAILURE); } /* Process the file, line by line */ nrErrors = 0; lineCount = 0; while (readLine(line, sizeof(line), fp, &lineOverflow) != NULL) { printf("Current line = \"%s\"", line); lineCount++; if (lineOverflow) { nrErrors++; printf(" (overflow in line: characters discarded.)\n"); } else printf("\n"); } printf("Lines processed = %d\n", lineCount); printf("Number of lines which didn't fit = %d\n", nrErrors); /* Close the stream */ fclose(fp); return 0; } /* Read and store one line of input return NULL if stream is at eof or there was a read error otherwise returns the pointer s to the char array reads and stores up to n characters in the char array, stopping at newline if there isn't space to hold the entire line, overflow is set to true and any trailing characters on that line are discarded */ char *readLine(char *s, int n, FILE *fp, bool *overflow) { int i; /* number of characters stored in the string */ int ch; /* most recent character read from the file */ int count; /* number of characters read */ i = 0; count = 0; /* Read characters on the current line, storing as many as will fit */ while (((ch = getc(fp)) != '\n') && (ch != EOF)) { count++; /* Safely deposit this character */ if (i < n - 1) /* hold one slot back for '\0' */ s[i++] = ch; } if ((count == 0) && (ch == EOF)) /* no characters read: at eof */ return NULL; /* Stream was not at eof, so a line has been read */ s[i] = '\0'; /* properly terminate the string */ /* Too many characters on this line? */ if (count > i) *overflow = true; else *overflow = false; return s; }