Why does Console.WriteLine() function miss some characters within a string?

后端 未结 7 2370
野的像风
野的像风 2021-02-12 10:42

I have a string, declared as:

 string text = \"THIS IS LINE ONE \"+(Char)(13)+\" this is line 2\";

And yet, When I write Console.WriteLin

相关标签:
7条回答
  • 2021-02-12 11:22

    The output isn't what it seems. Your terminal program is hiding you some characters of the bytes written in stdout because he interprets the carriage return presence as a text layout command (which is, go back to left). A hexdump can confirm that the output is correct by showing the very bytes of output.

    using System;
    public class Hello1 {
      public static void Main()  {
         string text = "THIS IS LINE ONE "+(Char)(13)+" this is line 2";
         System.Console.WriteLine(text);
       }   
    }
    

    Compile and run :

    $ gmcs a.cs
    $ ./a.exe
     this is line 2E
    $ ./a.exe | hexdump -C
    00000000  54 48 49 53 20 49 53 20  4c 49 4e 45 20 4f 4e 45  |THIS IS LINE ONE|
    00000010  20 0d 20 74 68 69 73 20  69 73 20 6c 69 6e 65 20  | . this is line |
    00000020  32 0a                                             |2.|
    00000022
    
    0 讨论(0)
  • 2021-02-12 11:30

    "A carriage return, sometimes known as a cartridge return and often shortened to CR, or return, is a control character or mechanism used to reset a device's position to the beginning of a line of text." (source)

    CR never changes a line, in fact it returns all the way to the beginning of "THIS IS LINE ONE " and prints " this is line 2" on top of it, hence why you see the additional E at the end of the sentence, as line one is one character longer. This is made clearer if you remove the two spaces from the two strings (last character of first string and first character of second string) where the output then becomes "this is line 2NE".

    From the same source:

    "It commands a printer, or other output system such as a display, to move the position of the cursor to the first position on the same line."

    What you're looking for is not CR, but a combination of CR and LF (line feed): CRLF

    0 讨论(0)
  • 2021-02-12 11:35

    Use string.Concat() to concatenate

    string text = String.Concat(...)
    

    and try to print this

    0 讨论(0)
  • 2021-02-12 11:36

    This is how standard output on the console behaves.

    • "\n" ((Char)10) will move the caret to the start of the next line
    • "\r" ((Char)13) will move the caret to the start of the current line

    As such, the results are thus the first line overwritten by the second line, leaving only the extra characters that the second line couldn't overwrite.

    Since you've clarified that the string/characters have to be like that to get the behavior you want when this text is ultimately sent to the place you actually want to send it to, a dot matrix printer, then you need to test with the printer itself.

    The above behavior is localized to the standard console. If you output the same characters to "standard output" but have redirected this to a printer, it is the printer's definition on how to deal with these characters that is important, and this may be different from the standard console.

    As such, the behavior you see on the standard console is just that, the behavior of the standard console. You need to actually test with the printer to see how this behaves.

    0 讨论(0)
  • 2021-02-12 11:37

    (Char)13 is a carriage return, while (Char)10 is a line feed. As others have said, this means that (Char)13 will return to the beginning of the line you are on, so that by the time you have written the (shorter) line 2, it will be written over the first section of the string - thus the remaining "E".

    If you try it with a shorter second string, you can see this happening:

    string text = "THIS IS LINE ONE " + (Char)13 +"test";
    Console.WriteLine(text);
    

    gives output:

    "test IS LINE ONE"
    

    Therefore, to solve your problem, the correct code will be:

    string text = "THIS IS LINE ONE " + (Char)10 +"test";
    Console.WriteLine(text);
    

    which outputs:

    THIS IS LINE ONE
    this is line 2
    

    Edit:

    Originally, since you said your printer requires it to be a (Char)13, I suggested trying both (Char)10 + (Char)13 (or vice versa) to achieve a similar effect. However, thanks to Peter M's exceedingly helpful comments, it appears the brand of printer you are using does in fact require just a (Char)10 - according to the manual, (Char)10 will produce a line feed and a carriage return, which is what you require.

    0 讨论(0)
  • 2021-02-12 11:40

    If you want this behavior:

    THIS IS LINE ONE [CR] //where the CR is a non printed character 
    this is line 2
    

    You need this code:

            char a = (char)10;
            string text = "THIS IS LINE ONE" + a + "this is line 2"
    
            Console.WriteLine(text);
    

    A carriage return((Char) 13) is a control character or mechanism used to reset a device's position to the beginning of a line of text, because of that you experience this behavior. Like I said you need (char)13 for your case.

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