特殊的转义字符—— \b 退格字符 ASCII 0x08

2023-11-06 06:59

本文主要是介绍特殊的转义字符—— \b 退格字符 ASCII 0x08,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引入

我们在写 C 语言题目时,经常会碰见类似于 数字 分隔符 数字 分隔符 数字 分隔符 这样的输出。比如下面这段代码:

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

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

新思路

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

#include <stdio.h>
#include <stdlib.h>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 <stdio.h>
#include <stdlib.h>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 字符的确是退格字符,但此退格非“删除”。“退格”就是字面含义上的退格,即“往前退一格”,相当于你在 Word 里按一下左方向键。

也就是说,\b 并不能删除上一个字符,它只是把光标往前移了一下而已

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

实际输出与显示

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

请看以下代码:

#include <stdio.h>
#include <stdlib.h>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 码为 0x08 的字符被原样输出了出来, 在文本编辑器里并没有实现退格的效果。
判题平台上使用的就是类似的方法,把程序的输出直接导出,传到网站上显示,但浏览器可不认 \b,于是就显示为了一个红点。

实际应用

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

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>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 <stdio.h>
#include <stdlib.h>
#include <windows.h>int main()
{//假设要做一个耗时较长的操作//为了更好的用户体验,我们需要一个进度条double progress = 0.1; //当前进度int length = 15; //进度条字符长度for (progress = 0.1; progress <= 1; progress += 0.05){//先输出 length 个 \b,把光标倒到开头去//也可以直接用一个 \rfor (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;
}

演示
在这里插入图片描述

这篇关于特殊的转义字符—— \b 退格字符 ASCII 0x08的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/355117

相关文章

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字

idea报错java: 非法字符: ‘\ufeff‘的解决步骤以及说明

《idea报错java:非法字符:‘ufeff‘的解决步骤以及说明》:本文主要介绍idea报错java:非法字符:ufeff的解决步骤以及说明,文章详细解释了为什么在Java中会出现uf... 目录BOM是什么?1. BOM的作用2. 为什么会出现 \ufeff 错误?3. 如何解决 \ufeff 问题?最

使用Java编写一个字符脱敏工具类

《使用Java编写一个字符脱敏工具类》这篇文章主要为大家详细介绍了如何使用Java编写一个字符脱敏工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、字符脱敏工具类2、测试工具类3、测试结果1、字符脱敏工具类import lombok.extern.slf4j.Slf4j

解决IDEA报错:编码GBK的不可映射字符问题

《解决IDEA报错:编码GBK的不可映射字符问题》:本文主要介绍解决IDEA报错:编码GBK的不可映射字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录IDEA报错:编码GBK的不可映射字符终端软件问题描述原因分析解决方案方法1:将命令改为方法2:右下jav

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

基于Python实现一个PDF特殊字体提取工具

《基于Python实现一个PDF特殊字体提取工具》在PDF文档处理场景中,我们常常需要针对特定格式的文本内容进行提取分析,本文介绍的PDF特殊字体提取器是一款基于Python开发的桌面应用程序感兴趣的... 目录一、应用背景与功能概述二、技术架构与核心组件2.1 技术选型2.2 系统架构三、核心功能实现解析

C# string转unicode字符的实现

《C#string转unicode字符的实现》本文主要介绍了C#string转unicode字符的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录1. 获取字符串中每个字符的 Unicode 值示例代码:输出:2. 将 Unicode 值格式化

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Perl 特殊变量详解

《Perl特殊变量详解》Perl语言中包含了许多特殊变量,这些变量在Perl程序的执行过程中扮演着重要的角色,:本文主要介绍Perl特殊变量,需要的朋友可以参考下... perl 特殊变量Perl 语言中包含了许多特殊变量,这些变量在 Perl 程序的执行过程中扮演着重要的角色。特殊变量通常用于存储程序的