特殊的转义字符—— \b 退格字符 ASCII 08
创始人
2024-02-17 05:04:43
0

引入

我们在写 C 语言题目时,经常会碰见这样的输出

1=1
1+2=3
1+2+3=6
1+2+3+4=10

如果用循环的话,这个加号是个大问题,如果直接用 printf("%d+"),最后会多一个加号,用 printf("+%d") 则前面会多一个加号。想要解决,则必须判断当前输出的是否为第一个或者最后一个数字,如果是,就不用输出加号。

新思路

有人就发现了,转义字符里有一个\b,这是个退格字符,能不能用它把多余的加号给删了呢?
那就试试呗,先输出个从 1 加到 5 试试

#include 
#include int main(void)
{int sum = 0;for (int i = 1; i <= 5; i++){printf("%d+", i);sum += i;}printf("\b");printf("=%d\n", sum);return 0;
}

好像没什么毛病,对吧?
在这里插入图片描述
让我们再提交到判题平台上试试
在这里插入图片描述
加号居然没删掉,而且还多了个点出来!

真实含义

我们把上面的代码稍稍改动一下

#include 
#include int main(void)
{int sum = 0;for (int i = 1; i <= 5; i++){printf("%d+", i);sum += i;}printf("\b");//printf("=%d\n", sum); //<---- 注释这一行return 0;
}

运行效果:
在这里插入图片描述
这段代码和上面的一模一样,只是把等号后面的输出给删掉了而已。**但是,最后的加号居然神奇地又出现了!**这是为什么呢?

我们先来看一下“退格”究竟为何含义。
\b 字符的确是退格字符,但此退格非彼退格,可不是键盘上的退格键。\b 这个退格就是字面含义上的退格,即“往前退一格”。
也就是说,一个单独的 \b 并不能删除上一个字符,他只是把光标往前移了一下而已。

那开头的代码为什么能正常输出呢?很简单,因为后面输出的字符覆盖掉了前面的字符,因此看起来好像是把上一个字符给删了。
为了更清晰的表示这个过程,我做了一个动图。(偷一下懒,图里只制作了三个数字求和,但原理是一样的。)
在这里插入图片描述
事实上退格键在早期打印机上的作用就是“往前退一格”,后来退格键的含义变了,变成了“往前退一格 + 删除一个字符”。

实际输出与显示

问题还没有完全解决:为什么在本地可以,但是上传到判题平台就不行了呢?
因为“显示的内容 ≠ 输出的内容”

请看以下代码:

#include 
#include int main()
{printf("123\n");printf("123\b\n");printf("123\b4\n");return 0;
}

运行结果
在这里插入图片描述

然而,我们把它编译,然后把程序的输出结果重定向到文件里,得到的结果是这样的:

123
123
1234

这段输出在不同的地方显示的内容可能不相同
Windows 记事本:一个框

Visual Studio 2015:啥也没有
在这里插入图片描述
Visual Studio 2019:一个带空心圈的实心框
![[Pasted image 20221125225938.png]]
Sublime:
![[Pasted image 20221125230132.png]]
**可以看到我们的 \b 字符,也就是 ASCII 码 0x8 的字符被原样输出了出来,**在文本编辑器里并没有实现退格的效果。判题平台上使用的就是类似的方法,把程序的输出直接导出,传到网站上显示,但浏览器可不认 \b,于是就显示为了一个红点。

实际应用

利用这个退格字符,我们可以做一个进度条出来
第一种:

#include 
#include 
#include int main()
{int index = 0;char ch[] = {'|', '\\', '-', '/'};while (1){putchar(ch[index]);index++;if (index >= 4)index = 0;Sleep(200); // Sleep(200) 的作用是延时 200 毫秒(0.2 秒)再继续执行下面的代码putchar('\b');}return 0;
}

演示
在这里插入图片描述

第二种:

#include 
#include 
#include int main()
{//假设要做一个耗时较长的操作//为了更好的用户体验,我们需要一个进度条double progress = 0.1; //当前进度int length = 15; //进度条字符长度for (progress = 0.1; progress <= 1; progress += 0.05){//先输出 length 个 \b,把光标倒到开头去for (int j = 0; j < length + 2; j++)putchar('\b');putchar('[');//已经完成部分的进度条int count = (int)(length * progress); for (int j = 0; j < count; j++)putchar('#');//未完成部分的进度条for (int j = 0; j < length - count; j++)putchar(' ');putchar(']');Sleep(100);}return 0;
}

演示
在这里插入图片描述

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...