tac
The tac Command
tac is cat spelled backward — it prints lines in reverse order:
$ printf "a\nb\nc\n" | tac
c
b
a
The last line becomes the first. The characters within each line are unchanged.
Your Implementation
Write void my_tac(const char *s) that prints lines in reverse order.
The challenge: you do not know the last line until you have scanned through the entire string. You need to store the line positions first, then print them in reverse.
void my_tac(const char *s) {
const char *starts[64]; // pointer to start of each line
int count = 0;
const char *p = s;
const char *line_start = s;
while (*p) {
if (*p == '\n') {
starts[count++] = line_start;
line_start = p + 1;
}
p++;
}
for (int i = count - 1; i >= 0; i--) {
const char *q = starts[i];
while (*q && *q != '\n') { putchar(*q); q++; }
putchar('\n');
}
}
Pointers as Array Entries
starts[count] = line_start stores a pointer (a memory address) in an array. Later, we use const char *q = starts[i] and walk forward with q++ until we hit '\n'.
This is a key C pattern: an array of pointers pointing into a larger buffer. It is how argv works — argv[0], argv[1], etc. are pointers into the program's argument memory.
Your Task
Implement my_tac that prints lines in reverse order. You can assume the input has at most 64 lines.