聊聊Windows程序中的"\r"和"\n"

     从学编程的第一天起,我们就接触到了"\r"和"\n"。 "\n" 表示换行(LF, Line Feed),ASCII是0xA。 "\r"表示回车(CR, Carriage Return), ASCII是0xD。 换行是很容易理解的,无需过多的解释。回车是打字机时代的产物,表示回到当前行的最开始。概念本身很简单,如果各个操作系统,框架都严格遵守这个规则,事情就简单多了。

   Unix系列, Apple OS X以及更高的系统,换行是"\n";微软的WIndows以及MS DOS 换行是"\r\n";苹果Macintosh OS 9以及更早, 换行是"\r"。这篇博客我想重点讲讲Windows下的换行。之所以要讨论这个问题,是因为我们在实际项目中遇到了和换行有关的问题,还困扰了我们好几天。

    问题的起因是这样的:我们需要做一个WPF控件,左边ListBox显示测试项,右边的RichTextBox显示所有内容,当选中左边任意测试项,右边RichTextbox会自动跳转到对应的测试项的首行。为了做到这点,我们需要算出所有测试项的总行数。我们最开始的做法是找出"\n"的个数,然后加1即得到总行数。绝大多数情况结果是对的,可是总有些时候,跳转结果是不对的。哪里出错了?

    为了彻底弄清这个问题,我们做了一些实验。首先是控制台程序。 

  static void Test()
        {
            string test = "hello1";
            Console.Write(test);
            test = "hello2\r\n";
            Console.Write(test);
            test = "hello3\n";
            Console.Write(test);
            test = "hello4\rworld\n";
            Console.Write(test);
            test = "hello5\r";
            Console.Write(test);

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
下面是输出结果:

hello1没有空行,所以hello2紧跟在hello1后面输出;

hello2后面跟\r\n,所以hello3在下一行打印;

同样,hello3后面跟\n,也独占一行;

hello4后面跟着\r,表明,输出hello4后,光标回到改行的第一位,这时再继续输出world会覆盖前面的hello,所以结果是world4;

同理,hello5被后面的Press any key to continue覆盖。


在控制台程序上,一切和我们预想的是一样的。那么为什么在WPF程序上会有出入呢?于是我们又做了一个WPF的demo

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            string content = "hello1\rhello2\n\rhello3\n\nhello4\r\r\nhello5\n\n\nhello6";

            Paragraph paragraph = new Paragraph(new Run(content));

            this.richtextbox.Document.Blocks.Add(paragraph);
        }
    }
下面是输出结果:

这回结果比较有趣了:

hello1后面我们跟的是\r,但实际效果却是换行;

hello2后面跟了\n\r,实际是换了两行;

hello4这个结果最想不到:后面跟了\r\r\n,预想它会换三行,但实际上却只换了两行!

通过更多的实验,我们发现在WPF控件中换行有一下规律:

\n     一行

\r\n   一行

\r\r\n  两行

\r\r     两行

如果需要在控件中计算总行数需要用下面这个公式

"\n" count  - "\r\n" count + "\r" count


我们又检查了当出现错误跳转时的源数据,果然发现有"\r\r\"的情况。 更新了计算公式后,我们的问题解决了。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值