What is the difference between \r and \n?

后端 未结 9 2224
庸人自扰
庸人自扰 2020-11-22 06:20

How are \\r and \\n different? I think it has something to do with Unix vs. Windows vs. Mac, but I\'m not sure exactly how they\'re different, and

相关标签:
9条回答
  • 2020-11-22 06:57

    In addition to @Jon Skeet's answer:

    Traditionally Windows has used \r\n, Unix \n and Mac \r, however newer Macs use \n as they're unix based.

    0 讨论(0)
  • \r is used to point to the start of a line and can replace the text from there, e.g.

    main()
    {
    printf("\nab");
    printf("\bsi");
    printf("\rha");
    }
    

    Produces this output:

    hai
    

    \n is for new line.

    0 讨论(0)
  • 2020-11-22 07:04

    in C# I found they use \r\n in a string.

    0 讨论(0)
  • 2020-11-22 07:05

    In C and C++, \n is a concept, \r is a character, and \r\n is (almost always) a portability bug.

    Think of an old teletype. The print head is positioned on some line and in some column. When you send a printable character to the teletype, it prints the character at the current position and moves the head to the next column. (This is conceptually the same as a typewriter, except that typewriters typically moved the paper with respect to the print head.)

    When you wanted to finish the current line and start on the next line, you had to do two separate steps:

    1. move the print head back to the beginning of the line, then
    2. move it down to the next line.

    ASCII encodes these actions as two distinct control characters:

    • \x0D (CR) moves the print head back to the beginning of the line. (Unicode encodes this as U+000D CARRIAGE RETURN.)
    • \x0A (LF) moves the print head down to the next line. (Unicode encodes this as U+000A LINE FEED.)

    In the days of teletypes and early technology printers, people actually took advantage of the fact that these were two separate operations. By sending a CR without following it by a LF, you could print over the line you already printed. This allowed effects like accents, bold type, and underlining. Some systems overprinted several times to prevent passwords from being visible in hardcopy. On early serial CRT terminals, CR was one of the ways to control the cursor position in order to update text already on the screen.

    But most of the time, you actually just wanted to go to the next line. Rather than requiring the pair of control characters, some systems allowed just one or the other. For example:

    • Unix variants (including modern versions of Mac) use just a LF character to indicate a newline.
    • Old (pre-OSX) Macintosh files used just a CR character to indicate a newline.
    • VMS, CP/M, DOS, Windows, and many network protocols still expect both: CR LF.
    • Old IBM systems that used EBCDIC standardized on NL--a character that doesn't even exist in the ASCII character set. In Unicode, NL is U+0085 NEXT LINE, but the actual EBCDIC value is 0x15.

    Why did different systems choose different methods? Simply because there was no universal standard. Where your keyboard probably says "Enter", older keyboards used to say "Return", which was short for Carriage Return. In fact, on a serial terminal, pressing Return actually sends the CR character. If you were writing a text editor, it would be tempting to just use that character as it came in from the terminal. Perhaps that's why the older Macs used just CR.

    Now that we have standards, there are more ways to represent line breaks. Although extremely rare in the wild, Unicode has new characters like:

    • U+2028 LINE SEPARATOR
    • U+2029 PARAGRAPH SEPARATOR

    Even before Unicode came along, programmers wanted simple ways to represent some of the most useful control codes without worrying about the underlying character set. C has several escape sequences for representing control codes:

    • \a (for alert) which rings the teletype bell or makes the terminal beep
    • \f (for form feed) which moves to the beginning of the next page
    • \t (for tab) which moves the print head to the next horizontal tab position

    (This list is intentionally incomplete.)

    This mapping happens at compile-time--the compiler sees \a and puts whatever magic value is used to ring the bell.

    Notice that most of these mnemonics have direct correlations to ASCII control codes. For example, \a would map to 0x07 BEL. A compiler could be written for a system that used something other than ASCII for the host character set (e.g., EBCDIC). Most of the control codes that had specific mnemonics could be mapped to control codes in other character sets.

    Huzzah! Portability!

    Well, almost. In C, I could write printf("\aHello, World!"); which rings the bell (or beeps) and outputs a message. But if I wanted to then print something on the next line, I'd still need to know what the host platform requires to move to the next line of output. CR LF? CR? LF? NL? Something else? So much for portability.

    C has two modes for I/O: binary and text. In binary mode, whatever data is sent gets transmitted as-is. But in text mode, there's a run-time translation that converts a special character to whatever the host platform needs for a new line (and vice versa).

    Great, so what's the special character?

    Well, that's implementation dependent, too, but there's an implementation-independent way to specify it: \n. It's typically called the "newline character".

    This is a subtle but important point: \n is mapped at compile time to an implementation-defined character value which (in text mode) is then mapped again at run time to the actual character (or sequence of characters) required by the underlying platform to move to the next line.

    \n is different than all the other backslash literals because there are two mappings involved. This two-step mapping makes \n significantly different than even \r, which is simply a compile-time mapping to CR (or the most similar control code in whatever the underlying character set is).

    This trips up many C and C++ programmers. If you were to poll 100 of them, at least 99 will tell you that \n means line feed. This is not entirely true. Most (perhaps all) C and C++ implementations use LF as the magic intermediate value for \n, but that's an implementation detail. It's feasible for a compiler to use a different value. In fact, if the host character set is not a superset of ASCII (e.g., if it's EBCDIC), then \n will almost certainly not be LF.

    So, in C and C++:

    • \r is literally a carriage return.
    • \n is a magic value that gets translated (in text mode) at run-time to/from the host platform's newline semantics.
    • \r\n is almost always a portability bug. In text mode, this gets translated to CR followed by the platform's newline sequence--probably not what's intended. In binary mode, this gets translated to CR followed by some magic value that might not be LF--possibly not what's intended.
    • \x0A is the most portable way to indicate an ASCII LF, but you only want to do that in binary mode. Most text-mode implementations will treat that like \n.
    0 讨论(0)
  • 2020-11-22 07:13

    \r is Carriage Return; \n is New Line (Line Feed) ... depends on the OS as to what each means. Read this article for more on the difference between '\n' and '\r\n' ... in C.

    0 讨论(0)
  • 2020-11-22 07:18

    In short \r has ASCII value 13 (CR) and \n has ASCII value 10 (LF). Mac uses CR as line delimiter (at least, it did before, I am not sure for modern macs), *nix uses LF and Windows uses both (CRLF).

    0 讨论(0)
提交回复
热议问题