22

I have a string, declared as:

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

And yet, When I write Console.WriteLine(text);,

the output is:

this is line 2E

Why is this behaviour happening? Or is it because I'm being stupid and missing something obvious?

Why does it not print:

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

EDIT

Please note: this is NOT a 'how do I add a carriage return' question.

Alexander Bell
  • 7,842
  • 3
  • 26
  • 42
jbutler483
  • 24,074
  • 9
  • 92
  • 145
  • Are you looking for a carriage return? (Char)(10)? – Drew Kennedy Nov 28 '14 at 15:56
  • It seems like the issue is specific just to Console.WriteLine() function. Did you observe such behavior in any other string operations, for example, trying to display the string via TextBox or TextBlock? Regards – Alexander Bell Nov 28 '14 at 15:57
  • I'm printing to a dot matrix printer – jbutler483 Nov 28 '14 at 16:02
  • Since we've now established that there is a printer involved. Are you piping the output of your console program to the printer, or are you simply dumping to the console for debugging purposes? – Lasse V. Karlsen Nov 28 '14 at 16:09
  • Given that the printer and the console output behave differently for the same output, you need to either change the printer, change the console or send different sequences to the console and the printer – Peter M Nov 28 '14 at 16:10
  • debugging only (so far), but since i'm still unsuccessful with the printer commands, I can't be certain – jbutler483 Nov 28 '14 at 16:10
  • 2
    So... We've established that you have a problem with the output on *the standard console* with output that *has to be like this for the printer to work*, except that *you have not yet tested how this behaves or works on the printer*. **Do you know for certain that you actually have a problem?** – Lasse V. Karlsen Nov 28 '14 at 16:12
  • 2
    Again, to iterate this. **This is how the standard output behaves**. If you don't like the output, change the text you write to it. If you can't because you're only doing this for debugging purposes and the text has to be like this for the printer, **stop testing with the standard console, test with the printer**. – Lasse V. Karlsen Nov 28 '14 at 16:12
  • @LasseV.Karlsen: Yes, I definitely have issues. – jbutler483 Nov 28 '14 at 16:13
  • 1
    How do you know, can you elaborate on the issues you actually have, so far all we know is that the issue you have with standard console is not a real issue that needs to be solved, or at the very least you know the solution to it, change the output. What *is* the issue with the printer? Does it behave the same way on the printer? – Lasse V. Karlsen Nov 28 '14 at 16:14
  • 1
    @LasseV.Karlsen: I've already got another [question for that](http://stackoverflow.com/questions/27187463/sending-system-printer-commands-to-dot-matrix-printer) it was more *"if i can't see the command working on the console, how is it meant to work on the printer"* – jbutler483 Nov 28 '14 at 16:16
  • 3
    Ok, let me spell it out then. The printer and the console **may behave differently**. The only way to know for sure is to test with the actual device, the printer. This is not a problem with `Console.WriteLine`, and not a problem with the actual characters, it is a "problem" with the standard console behavior. The printer may or may not behave the same way, the behavior of the console has no impact on this. – Lasse V. Karlsen Nov 28 '14 at 16:17
  • 5
    Your program just gave all those characters to the standard console and asked it to show them, **it** behaved like that in regards to newline characters. The printer may behave completely different. In fact, old dot matrix printers used one character to just move the head down one line and keep going where it was X-wise, and the other character to move to the start of the line, as such you needed both to get what you want. You will only figure this out if you test with the actual printer. – Lasse V. Karlsen Nov 28 '14 at 16:18
  • 3
    As per your other question where you mention an OKI Microline 5520.. I just found http://www.manuals365.com/swf/oki/552xugb2_tcm3-46086.html?page=74 Which implies that you want Char 10 and not Char 13. – Peter M Nov 28 '14 at 16:22
  • @PeterM: Thank you for that Link. I believe that could come in quite handy. – jbutler483 Nov 28 '14 at 16:27
  • What intrigues me is the "E" at the end, coming from nowhere. – Nicolas Barbulesco Nov 29 '14 at 07:21
  • 1
    @NicolasBarbulesco It's left over from printing the first line and not covering that entirely with the second. See answers below. – Daniel Fischer Nov 29 '14 at 09:40

7 Answers7

58

(char)13 is a carriage return (To the left margin on the current line)

THIS IS LINE ONE \r this is line 2"

Is interpreted as:

Print THIS IS LINE ONE
then *return* and print this is line 2
The overlap is: E
So you see: this is line 2E

Alex K.
  • 171,639
  • 30
  • 264
  • 288
  • this is correct, there's no issue when strings are of equal length, e.g. `string text = "THIS IS LINE ONE " + (Char)(13) + " THIS IS LINE TWO";` – globetrotter Nov 28 '14 at 16:14
  • 2
    What do you mean no issue? Is the issue that there are leftover characters from the first line, or is it that the cursor doesn't move to the second line (which is what the OP seems to indicate) – Lasse V. Karlsen Nov 28 '14 at 16:15
  • 1
    @LasseV.Karlsen Alex K. explained this nicely. It returns to the beginning of line 1 and prints line 2 on top of line 1. Because line 1 is longer, there's an overhead, hence the extra 'E' char at the end of the line. For a new line you would do `(char)10` – globetrotter Nov 28 '14 at 16:20
  • 1
    Yes, and the OP asked how to get `(char)13` to move to the next line. The issue for the OP was thus never about the leftover characters, it was why it didn't move down to the second line instead of overwriting. So yes, the answer explains nicely why the output *looks* that way, but for the OP there is still an issue. Though the OP will just have to settle for not getting what he wants I think. – Lasse V. Karlsen Nov 28 '14 at 16:22
  • @LasseV.Karlsen I understand what you're saying but `(char)13` is not supposed to move to the next line. This is `CR`, that would be `CRLF` – globetrotter Nov 28 '14 at 16:24
  • All this hinged on the fact that the OP said his printer behaved like this. As it turns out, it doesn't so I suspect this whole page of text is moot and pretty useless. – Lasse V. Karlsen Nov 28 '14 at 16:27
20

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.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
5

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.

mybirthname
  • 17,949
  • 3
  • 31
  • 55
4

"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

trashr0x
  • 6,457
  • 2
  • 29
  • 39
2

(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.

Luna
  • 391
  • 5
  • 15
  • 2
    Dot matrix printer commands can be a `black art` and can be very very manufacturer specific, so I wouldn't proclaim any solution for a printer until you knew the exact make and model - and had one on your desk that you had tested the code with - and only if you were going to deploy that exact printer. :-) – Peter M Nov 28 '14 at 16:15
  • That's a fair point - I've edited my answer to suggest it as something that could be tried rather than as a complete solution. If this makes it an irrelevant answer in the OP's case, although it does solve the issue on my computer, I can delete it. :-) – Luna Nov 28 '14 at 16:18
  • 3
    The OP revealed that he another question which mentions the printer involved. I googled the commands and found http://www.manuals365.com/swf/oki/552xugb2_tcm3-46086.html?page=74 Feel free to incorporate that in you answer! – Peter M Nov 28 '14 at 16:21
  • And from my reading of that reference he wants Char 10 anyway! – Peter M Nov 28 '14 at 16:23
  • 1
    @PeterM: While dot-matrix commands vary between manufacturers, at least historically I've found them relatively straightforward. I would expect that printers which are capable of overprinting would generally regard "CR" as a command to overprint what follows starting at the beginning of the same line; only devices which use the same motor to drive the carriage and paper feed would be unable to manage that. – supercat Nov 29 '14 at 00:29
2

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
Nope
  • 897
  • 1
  • 8
  • 15
-2

Use string.Concat() to concatenate

string text = String.Concat(...)

and try to print this

jbutler483
  • 24,074
  • 9
  • 92
  • 145
Anton Kozlovsky
  • 203
  • 1
  • 15