为什么 Console.WriteLine() 函数会丢失字符串中的某些字符

本文关键字:字符串 字符 WriteLine Console 函数 为什么 | 更新日期: 2023-09-27 18:32:20

我有一个字符串,声明为:

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

然而,当我写Console.WriteLine(text);时,

输出为:

this is line 2E

为什么会发生这种行为?还是因为我愚蠢,错过了一些明显的东西?

为什么不打印:

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

编辑

请注意:这不是"如何添加回车"的问题。

为什么 Console.WriteLine() 函数会丢失字符串中的某些字符

(char)13是一个回车(到当前行的左边距)

THIS IS LINE ONE 'r this is line 2"

被解释为:


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

这就是控制台上标准输出的行为方式。

  • "'n"(Char)10 ) 会将插入符号移动到下一行的开头
  • "'r"(Char)13 ) 会将插入符号移动到当前行的开头

因此,结果是第一行被第二行覆盖,只留下第二行无法覆盖的额外字符。

既然你已经澄清了字符串/字符必须像这样才能获得你想要的行为,当这个文本最终发送到你实际想要发送到的地方,一个点阵打印机,那么你需要使用打印机本身进行测试。

上述行为已本地化为标准控制台。如果将相同的字符输出到"标准输出",但已将其重定向到打印机,则打印机对如何处理这些字符的定义很重要,这可能与标准控制台不同

因此,您在标准控制台上看到的行为就是标准控制台的行为。您需要使用打印机实际测试以查看其行为。

如果需要此行为:

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

您需要以下代码:

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

回车符((Char) 13) 是一种控制字符或机制,用于将设备的位置重置为文本行的开头,因此您会遇到此行为。就像我说的,你需要(字符)13 来对待你的情况。

"回车

,有时称为墨盒回车,通常 缩写为CR,或返回,是控制字符或机制 用于将设备的位置重置为文本行的开头。(来源)

CR从不更改一行,实际上它会一直返回到"THIS IS LINE ONE "的开头并在其顶部打印" this is line 2",因此您在句子末尾看到额外的E,因为第一行长一个字符。如果从两个字符串(第一个字符串的最后一个字符和第二个字符串的第一个字符)中删除两个空格,则输出变为"this is line 2NE",则会更清楚。

来自同一来源:

"它命令打印机或其他输出系统(如显示器)以 将光标的位置移动到同一位置上的第一个位置 行。

您要查找的不是CR,而是CRLF(换行)的组合: CRLF

>(Char)13是回车符,而(Char)10是换行符。正如其他人所说,这意味着 (Char)13 将返回到您所在行的开头,因此当您编写(较短的)第 2 行时,它将写入字符串的第一部分 - 因此剩余的"E"。

如果您尝试使用较短的第二个字符串,您可以看到这种情况发生:

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

给出输出:

"test IS LINE ONE"

因此,要解决您的问题,正确的代码将是:

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

其中输出:

THIS IS LINE ONE
this is line 2

编辑:

最初,由于您说您的打印机要求它是(Char)13,我建议尝试两种(Char)10 + (Char)13(反之亦然)以实现类似的效果。然而,由于Peter M的非常有用的评论,看来你正在使用的打印机品牌实际上只需要一个(Char)10 - 根据手册,(Char)10将产生换行符和一个回车符,这正是你需要的。

输出不是看起来的那样。您的终端程序隐藏了用 stdout 编写的字节的一些字符,因为他将回车状态解释为文本布局命令(即返回左侧)。十六进制转储可以通过显示输出的字节数来确认输出是否正确。

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);
   }   
}

编译并运行:

$ 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

使用 string.Concat() 连接

string text = String.Concat(...)

并尝试打印此