我正在使用ubuntu。代码:
printf("Hellonb world");
我上了终端:
Hello
world
为什么退格不取消?字符中有层次结构吗?
如何删除特殊字符?
您的问题超出了C语言的范围:printf("Hellonb world");
从格式字符串中输出字节,可能根据换行符的文本模式处理进行翻译:
-
在unix系统上,字节未经修改地输出到系统句柄。
-
在Microsoft遗留系统上,换行符被转换为CR LF,其他字节未经修改地传输。
如果标准输出指向一个文件,该文件将包含换行符和退格符的转换(在大多数系统上为0x08)。
如果标准输出到终端,退格特殊字符的处理超出了程序的控制范围:终端(硬件、虚拟、本地或远程…)将按照编程和配置执行任务。。。大多数终端在其控制的任何显示器上都会将光标向左移动一个位置,有些则会擦除该位置的字符。如果光标已经在第1列,那么无论这意味着什么,退格是否将光标移回前一行的末尾都取决于系统。许多系统不这样做,而是将光标保持在第1列。这似乎与你观察到的行为一致。
这些转义序列b
和n
表示控制字符。控制字符是一种特殊的字符,它以某种特殊的方式控制输出设备的行为。当你说
printf("A");
它将(普通)字符CCD_ 4打印到屏幕上。但是当你说
printf("n");
它不打印任何内容,而是将光标向下移动到下一行的开头。
现在b
的含义是而不是";取消左边的字符";。控制字符CCD_;取消";任何东西它所做的只是将光标向左移动一个字符(如果可以的话)。但是,如果光标已经位于左边缘,则可能无法。
曾几何时,尤其是当输出被送到真正在纸上打印的打印机时,像这样的事情很常见
printf("this is ub_nb_db_eb_rb_lb_ib_nb_eb_db_n");
或
printf("this is bbbobolbldbdn");
通过套印印刷带下划线或粗体字。这些例子显然依赖于CCD_ 7的向左移动行为。这些例子证明了CCD_;取消"!
听起来你认为b
可能会以某种方式影响它所属的字符串。听起来您认为b
可能会以某种方式由C编译器或C库处理。听起来您认为字符串"abcbdef"
可能会转换为"abdef"
。但这些都不是真的。退格字符b
由您的屏幕或打印机或您的程序的任何输出设备来解释;打印";到。像b
这样的控制字符的解释主要取决于您的输出设备。它在很大程度上不是C编程语言的属性。
这是C标准(在C 2018 5.2.2 2中)对换行符的描述
将活动位置移动到下一行的初始位置。
和退格:
将活动位置移动到当前行的上一个位置。如果活动位置位于线的初始位置,则显示设备的行为是未指定的。
请注意,没有指定退格字符来擦除前一个字符。它被指定为在显示设备上引起特定的操作。
回想一下,C是在电传打字机和其他物理打印设备普遍使用的时代开发的。其中许多设备只能将纸张向上推。一旦一个换行符导致纸张被向上推,就没有办法再次向下移动。
此外,一些早期的视频显示器或驱动它们的软件模拟了物理打印,不支持回退一行,至少在某些操作模式下是这样。
在可以自由移动光标的显示器上,不清楚从一行开始的退格应该做什么。考虑一个显示器,它有80列,编号从1到80,打印的最后一行包含40个字符,后面跟着一行新行。当我们退格时,我们将光标移回那一行,但我们将光标移动到哪一列?第80列,显示的最后一个?还是第40栏,最后一个印刷的地方?不同的设备可能会以不同的方式处理此问题。请注意,后一种选择要求设备记住每条线的长度,这给早期的计算机器增加了负担。(我高中的廉价显示终端没有足够的内存来记住24×80显示器中的所有文本。我认为它只有1024个字节,足以容纳12.8行80个字符。如果你写了完整的文本行,它会从显示器上滚动前几行,只保留最后12行。)
由于这些行为上的变化,C标准没有指定从一行开始的退格细节。
你问"退格转义"取消了"换行转义"。然而,转义序列在这里无关紧要;它们与字符的操作处于不同的表示层:
- 在字符串文字中,
b
和n
是转义序列。当编译器翻译程序时,它会用退格字符和换行符替换这些字符。然后它们不再是转义序列;它们只是字符串中的字符 - 使用
printf
编写字符时,它们将作为流中的字符进行传输 - 当字符被发送到显示设备时(因为这就是流所连接的),它们会产生上面引用的5.2.2 2文本中的动作