#include #include // Returns pointer to a line read from fp (excluding line-ending), returns NULL // on error or if EOF is reached. #define INITIAL_SIZE 1 #define INCREMENT 1 static char *read_line(FILE *fp) { int c, bufsize = INITIAL_SIZE, len = 0; char *buffer = (char *) malloc(sizeof(char) * INITIAL_SIZE); if (buffer == NULL) return NULL; while (1) { c = fgetc(fp); if (c == EOF) { if (len == 0) { // Reached end of line without actually reading anything, return NULL; free(buffer); return NULL; } break; } else if (c == '\n') { break; } else if (c == '\r') { // Mac or Win line-ending // Attempt to read optional \n (Win line-ending). c = fgetc(fp); if (c != '\n') ungetc(c, fp); break; } else { if (len > bufsize-1) { // TODO: handle realloc returning NULL properly bufsize += INCREMENT; buffer = (char *) realloc(buffer, sizeof(char) * bufsize); if (buffer == NULL) fprintf(stderr, "oh crap\n"); } buffer[len] = c; len++; } } buffer[len] = '\0'; return buffer; } int main(int argc, char **argv) { FILE *file; char *line; if (argc < 2) { printf("Add filename to read as commandline argument\n"); return 1; } if ( (file = fopen(argv[1], "rb")) == NULL ) { fprintf(stderr, "Failed to open file.\n"); return 1; } while ((line = read_line(file)) != NULL) { printf("line read: %s\n", line); free(line); } return 0; }