/* Name: incorrect-readfile5.c Purpose: Similar to readfile4.c, with yet another implementation of readLine Author: Bill Slough and Joe College WARNING: DO NOT USE THIS CODE FOR ANY PURPOSE. INTENDED FOR INSTRUCTIONAL USE ONLY. Bugs: 1. ????????? 2. ????????? */ #include #include #include #define FILE_NAME "words" /* name of the input file */ #define SIZE 10 void *safe_malloc(size_t size); void *safe_realloc(void *ptr, size_t size); char *readLine(FILE *fp); int main(void) { FILE *fp; /* file pointer for an input stream */ int lineCount; /* number of lines processed */ char *line; /* 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); } /* read and process the input stream */ lineCount = 0; while ((line = readLine(fp)) != NULL) { printf("Current line = \"%s\"\n", line); lineCount++; } printf("Lines processed = %d\n", lineCount); /* Close the stream */ fclose(fp); return 0; } /* safely allocate a block of storage, aborting program if not possible */ void *safe_malloc(size_t size) { void *p; p = malloc(size); if (p == NULL) { fprintf(stderr, "error - out of space!"); exit(EXIT_FAILURE); } else return p; } /* safely re-allocate a block of storage, aborting program if not possible */ void *safe_realloc(void *ptr, size_t size) { ptr = realloc(ptr, size); if (ptr == NULL) { fprintf(stderr, "error - out of space!"); exit(EXIT_FAILURE); } else return ptr; } /* Read and store one line of input from a FILE 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 characters in the char array, stopping at newline if there isn't space to hold the entire line, double the space is re-allocated until the line fits, and then the space is trimmed to match the size of the string */ char *readLine(FILE *fp) { char *s; int i, ch, count, size; i = 0; count = 0; size = SIZE; /* Read characters on the current line, storing as many as will fit */ s = safe_malloc(SIZE); while (((ch = getc(fp)) != '\n') && (ch != EOF)) { count++; /* Safely deposit this character */ if (i < size - 1) { /* there is still room */ s[i++] = ch; } else { size = size * 2; /* double the size for reallocation */ s = safe_realloc(s, size); 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 */ s = safe_realloc(s, count + 1); /*reduce allocated memory to fit string*/ printf("readLine: buffer has %d allocated bytes. ", count + 1); return s; }