If you can set some maximum line length, you can read lines using standard C fgets() function. If you're on recent POSIX-compliant operating system, or have GNU glibc, you can use getline(), which will allocate memory for line, so you can read any line length. See this answer here at SO.
For each line, you will then get char* pointer.
If you can set maximum number of lines to support, you can use char *lines[MY_MAX_LINE_COUNT] to store the pointers, and then simply print in reverse order from array. Better is to implement a very simple linked list which allows prepending (this is probably the most simple linked list code there can be, basically a stack with just push, no need for pop...), and then print lines from that when all have been read.
For the simple case, to avoid allocating a linked list struct for every line, it might be best to store the char* line pointers into an array, which is grown using realloc():.
First the variables that are need:
int arraysize = 16; /* any size will do, 16 is nice round number */
char *lines[16] = malloc(sizeof(char*) * arraysize);
int linecount = 0;
Then loop to get input:
while(/* test for eof or whatever */) {
char *line = /* code to get the line */;
if (linecount == arraysize) {
arraysize *= 2;
lines = realloc(lines, sizeof(char*) * arraysize);
}
lines[linecount] = line; /* old lines are at indexes 0..(linecount-1) */
++linecount;
And printing loop for that:
for(int index = linecount-1 ; index >= 0 ; --index) {
puts(lines[index]); /* if line has newline stripped, else printf("%s", lines[index]);
}