First you would need to write a getline routine, which reads in a variable-length line. It will be allocated with malloc:
#define INITALLOC  16  /* #chars initally alloced */
#define STEP        8  /* #chars to realloc by */
int getline(char **dynline)
{
    int i, c;
    size_t nalloced;  /* #chars currently alloced */
    if ((*dynline = malloc(INITALLOC)) == NULL)
        return 0;
    nalloced = INITALLOC;
    for (i = 0; (c = getchar()) != EOF && c != '\n'; ++i) {
        /* buffer is full, request more mem */
        if (i == nalloced)
            if ((*dynline = realloc(*dynline, nalloced += STEP)) == NULL)
                return 0;
        /* store the newly read character */
        (*dynline)[i] = c;
    }
    /* zero terminate the string */
    (*dynline)[i] = '\0';
    if (c == EOF)
        return 0;  /* return 0 on EOF */
    return 1;
}
This function returns 0 on failure or EOF, and 1 on success. Now we can read the lines in our main function.
int main()
{
    char *line;
    while (getline(&line))
        printf("%s\n", line);
    /* free to avoid mem leak */
    free(line);
    return 0;
}
And do not use while(!feof(fp)), because this will always result in one extra read, because the EOF state is set only after you try to read, not before.