关于\r和\n

143 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第27天,点击查看活动详情

回车键的作用

我们打字的时候,不管在什么编辑器里,或者是在网页里,回车键,都可以让你换到下一行的行首位置。

让我们仔细观察一下这个过程,先看看你键盘上的回车键的图像,一般是一个带有转折的箭头,由向下和向左组成。

这说明了回车键按下去之后,其实发生了两个操作:

  • 向下
  • 向左

文件中的换行

由于Windows和Linux是各自发展的,所以这个换行符一直以来是最烦人的区别之一。

在Linux中,文件换行符是单个字符\n, 这一个字符代表两个回到行首和跳到下一行两个过程。

在Windows中,文件换行符是两个字符\r\n

其中, \r代表回到行首, \n 代表跳到下一行。

命令行中的换行

这个和文件的换行一样,也是发生了两个过程,而且,这两个过程可以拆分。

命令行的\r可以用来搞花活

由于\r只是回到行首,并没有将光标跳到下一行,所以,我们如果仅仅\r再输出字符的话,就会覆盖本行的内容。

这就好像,你打字的时候,将光标移动到行首,然后按一下键盘上的INS键,你接着输入,新输入的字,会覆盖这一行的老内容。

搞一个loading旋转特效

很多命令行程序在下载包或者编译安装等耗时的操作时,都会搞一个命令行上的loading效果,来让你不要那么着急。

我们现在就来实现这个特效。

原理就是,将这四个字符:

/-\|

循环打印出来即可,但是,每个字符输入之后,马上加一个\r

然后循环的时候,加一定的时间间隔。

看一下这个代码:

package main

import (
	"fmt"
	"time"
)

func main() {
	data := []byte{'/', '-', '\\', '|'}
	for {
		for idx := range data {
			time.Sleep(time.Second)
			fmt.Printf("%c\r", data[idx])
		}
	}
}

直接运行,就可以看见,loading的旋转效果了。

这里注意的是,\这个字符,在代码中书写的时候,需要'\\',转义一下。

如果你嫌慢,可以将Sleep的时间缩短一点。比如说调成 20ms20 ms。这时候,旋转感就很强了。

搞一个向右移动的箭头

原理分析:先打印一个向右的箭头,然后\r退回去,然后打印一个空格加一个箭头,然后再\r,然后逐步增加空格的个数,这样一直循环下去:


package main

import (
	"fmt"
	"time"
)

func main() {
	for {
		for idx := 0; idx != 10; idx++ {
			time.Sleep(time.Millisecond * 20)
			for jdx := 0; jdx != idx; jdx++ {
				fmt.Printf(" ")
			}
			fmt.Printf("-->\r\a")
		}
	}
}

扩展,退回上一行

如果你想要退回到上一行,也是可以做到的。

只要打印

\033[A

这几个字符,就可以退回到上一行。

打印上面的字符N次,就可以退回N行。

这样完全可以做一个清屏的效果出来。

然后在干净的屏幕上,利用 \r\033[A 搞一个动画什么的。

比如说,一个sl命令,一个小火车就飞过去也是可以做到的。