It is not beginner friendly but it is optimized. It doesn't allocate memory or whatever. I don't expect you to understand all this but I did it for fun anyway.
int print_file(const char* buffer)
{
// Validate the buffer
if (!buffer || *buffer == '\0') return 1;
// Prepare the first line prefix
unsigned int line = 1;
printf("%4d\t", line); // You could pre-format it if u want
const char* cursor = buffer; // The pointer that points to the first char
const char* linestart = cursor; // The start of the line
char ch; // Character register
while (true) {
ch = *cursor++; // Read character THEN advance the cursor.
// Check if the character is null or is newline or windows thing
if (ch == '\0') {
int linelength = cursor - linestart - 1; // Minus the null terminator
printf("%.*s\n", linelength, linestart); // Print line using the length of string
break;
} else if (ch == '\n') {
int linelength = cursor - linestart - 1; // Minus the newline
printf("%.*s\n", linelength, linestart); // Print line using the length of string
linestart = cursor;
printf("%4d\t", ++line); // Print next line prefix
} else if (ch == '\r') {
continue; // Ignore the Windows thing
}
}
return 0;
}