【问题标题】:Why does Console.WriteLine() function miss some characters within a string?为什么 Console.WriteLine() 函数会丢失字符串中的某些字符?
【发布时间】:2014-11-28 15:46:35
【问题描述】:

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

 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 的问题,也不是实际字符的问题,这是标准控制台行为的“问题​​”。打印机的行为方式可能相同,也可能不同,控制台的行为对此没有影响。
  • 你的程序只是将所有这些字符提供给标准控制台并要求它显示它们,在换行符方面表现得像这样。打印机的行为可能完全不同。事实上,旧的点阵打印机使用一个字符将头部向下移动一行并继续沿 X 方向移动,而另一个字符则移动到行首,因此您需要两者来获得您想要的想。只有在使用实际打印机进行测试时,您才会知道这一点。
  • 根据您提到 OKI Microline 5520 的其他问题。我刚刚找到 manuals365.com/swf/oki/552xugb2_tcm3-46086.html?page=74 这意味着您想要 Char 10 而不是 Char 13。

标签: c# string console char console.writeline


【解决方案1】:

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

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

【讨论】:

  • 很好的解释!
  • 这是正确的,当字符串长度相等时没有问题,例如string text = "THIS IS LINE ONE " + (Char)(13) + " THIS IS LINE TWO";
  • 没问题是什么意思?是第一行有剩余字符的问题,还是光标没有移动到第二行(这似乎是 OP 所表示的)
  • @LasseV.Karlsen Alex K. 很好地解释了这一点。它返回到第 1 行的开头并在第 1 行的顶部打印第 2 行。因为第 1 行较长,所以存在开销,因此在行尾有额外的 'E' 字符。对于新行,您可以使用 (char)10
  • 是的,OP 询问如何让(char)13 移动到下一行。因此,OP 的问题与剩余字符无关,这就是为什么它没有下移到第二行而不是覆盖的原因。所以是的,答案很好地解释了为什么输出 looks 那样,但对于 OP 来说仍然存在问题。尽管我认为 OP 将不得不接受没有得到他想要的东西。
【解决方案2】:

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

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

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

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

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

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

【讨论】:

    【解决方案3】:

    如果你想要这种行为:

    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) 是一个控制字符或机制,用于将设备的位置重置为文本行的开头,因为您会遇到这种行为。就像我说的那样,您的情况需要 (char)13。

    【讨论】:

    • 这实际上是正确的,但我需要它是打印机的 char(13)(因为这是它期望看到的)。
    • @jbutler483 然后创建自己的 WriteLine 方法,将 13 替换为 10...?
    【解决方案4】:

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

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

    来自同一来源:

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

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

    【讨论】:

      【解决方案5】:

      (Char)13carriage return,而 (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 非常有用的 cmets,看来您使用的打印机品牌实际上只需要 (Char)10 - 根据 the manual(Char)10 将产生换行符和回车符,即你需要什么。

      【讨论】:

      • 点阵打印机命令可以是 black art 并且可以是非常特定于制造商的,所以在您知道确切的品牌和型号之前,我不会宣布任何打印机解决方案 - 并且有一个您已经测试过代码的办公桌 - 并且仅当您要部署该确切的打印机时。 :-)
      • 这是一个公平的观点 - 我已经编辑了我的答案,建议将其作为可以尝试的东西,而不是作为一个完整的解决方案。如果这使得它在 OP 的情况下成为一个无关紧要的答案,虽然它确实解决了我计算机上的问题,但我可以将其删除。 :-)
      • OP 透露他的另一个问题提到了所涉及的打印机。我用谷歌搜索了这些命令,发现 manuals365.com/swf/oki/552xugb2_tcm3-46086.html?page=74 随意将其合并到您的答案中!
      • 从我对那篇参考文献的阅读来看,他还是想要 Char 10!
      • @PeterM:虽然点矩阵命令因制造商而异,但至少从历史上看,我发现它们相对简单。我希望能够叠印的打印机通常会将“CR”视为叠印从同一行开头开始的内容的命令;只有使用相同电机驱动托架和进纸的设备才能做到这一点。
      【解决方案6】:

      输出并非看起来那样。您的终端程序向您隐藏了 stdout 中写入的字节的一些字符,因为他将回车解释为文本布局命令(即返回到左侧)。 hexdump 可以通过显示 output 的字节数来确认 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);
         }   
      }
      

      编译运行:

      $ 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
      

      【讨论】:

        【解决方案7】:

        使用string.Concat() 连接

        string text = String.Concat(...)
        

        并尝试打印此内容

        【讨论】:

        • 这并不能改变打印输出不正确的事实。
        • C# 中的+ 符号导致调用String.Concat(除了这种情况,可以在编译时执行连接)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多