Mainframes traditionally use fixed-width record sizes to represent "lines." (Or "cards" if you really think their way.)
Unix, C, C++ '\n'. (And '^D', not stored in the file, for end of file.)
CP/M, MS-DOS, Windows: '\r\n', the physical representation for most "terminals." (And '^Z', in the file, for "end of text in this file." With "junk" to fill the rest of the fixed-size block.)
Original Apple Mac: '\r' (or so I've read)
PICK OS: hex 'FE' character for line separator
@ddlyh @b0rk @ben
The "logical" representation, stored in memory or disk, does not have to correspond exactly to the "physical" representation sent to the terminal/printer.
But in CP/M's case, it does simplify things: No translation; just dump text file contents to the console stream, "raw." The implementation of the "TYPE" command is "stream bytes until you hit '^Z' or end of file, and stop."