/* Name: readfile3.c Purpose: Similar to readfile2.c, with improvements 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 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\"\n", line); lineCount++; if (lineOverflow) nrErrors++; } 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) { char *result; int length; int ch; int skipped; /* the number of NON-newline characters skipped over for lines too long to fit in the given char array */ result = fgets(s, n, fp); /* read a line */ if (result == NULL) { *overflow = false; return NULL; /* either stream is at eof or there was a read error */ } /* read was successful: did we get the entire line? */ length = strlen(s); if (s[length - 1] == '\n') { s[length - 1] = '\0'; /* we don't want to store the newline */ *overflow = false; } else { /* skip to end of current line */ skipped = 0; while ((ch = getc(fp)) != '\n' && (ch != EOF)) skipped++; *overflow = (skipped > 0); } return s; }