编程语言中制表符的打印和输出@C#为例进行说明
文章目录
- 编程语言中制表符的行为
- 字符串中的制表符的行为
- 输出带有制表符的字符串的对齐问题
- 说明
- 补全代码:
- 解释输出没有对齐的原因:
- 制表符行为实验👺
- 改进后的代码
- 格式化说明:
- 输出:
- 总结:
编程语言中制表符的行为
大多数编程语言的字符串打印语句中的制表符\t
的输出遵循相同的规则
从结果上看,制表符的作用是尽力而为,让以\t
为分割符的字符串字段之间不挨在一起,同时对于多行数据,尽可能对齐
这种策略对于各个字段长度相近的时候效果比较好,尤其是每个字段长度都小于制表符对空格的当量,比如一个制表符对应(最多)8个空格时,当所有字段都是小于8个字符(0~7)时,那么输出的表格将会很整齐;但是对于字段长度差异较大的情况,对齐效果就不是那么好
总之,制表符不是那么智能,能够对齐复杂情况的代码不是只靠一个制表符就能搞定
字符串中的制表符的行为
形式化描述为:若字符串A\tB
(其中A,B是字符串,A前面是换行符或者为空,\t
制表符对应的空格数量为
n
n
n),并设A,B的字符数量分别为
a
,
b
a,b
a,b;那么
a
a
a除以
n
n
n的结果
r
r
r,式子
w
=
n
−
r
w=n-r
w=n−r=
n
−
(
a
%
n
)
n-(a\%{n})
n−(a%n)就是A,B之间的空格数量;
例如, a = 7 a=7 a=7, n = 4 n=4 n=4,那么 w = 4 − ( 7 % 4 ) w=4-(7\%{4}) w=4−(7%4)= 4 − 3 = 1 4-3=1 4−3=1,也就是字符串A和B之间的间隔是1个空格
如果上述结论是对的话,那么
- 设置制表符对应的空格数大一些,可以更大的几率让表格数据各行各列对齐
- 在适当的位置连续使用多个制表符
- 使用固定字段长度的输出控制实现整齐输出
输出带有制表符的字符串的对齐问题
C#为例
练习 - 使用转义字符序列设置输出格式 - Training | Microsoft Learn
-
To format your output as aligned columns of text, replace the spaces between words with the
\t
escape sequence as follows:C#
Console.WriteLine("Student\tGrade\n"); Console.WriteLine("Sophia:\t" + sophiaScore + "\tA"); Console.WriteLine("Nicolas:\t" + nicolasScore + "\tB"); Console.WriteLine("Zahirah:\t" + zahirahScore + "\tB"); Console.WriteLine("Jeong:\t" + jeongScore + "\tA");
The
\t
escape sequence will insert a tab stop between the text items. Adding the tab stops should result in left-aligned columns of information. -
To view the results of your updates, select Run.
-
Compare the output of your application with the following output:
Student Grade Sophia: 94.6 A Nicolas: 83.6 B Zahirah: 83.4 B Jeong: 95.4 A
-
Notice that despite using a tab instead of a space character, some lines still don’t have much whitespace between the student’s name and their numeric score.
This difference is due to the way that tab spacing is applied.
Tab stop locations are set at four-character intervals, and each tab will advance to the next tab stop location.
If you have a string of five characters followed by a tab escape sequence, the escape sequence will advance to the tab stop at the eight-character location, filling the gap with space characters to create whitespace in the output. However, you can advance to the same location if you have a string of seven characters followed by a tab escape sequence. This makes tab escape sequences more noticeable when they occur further from the next tab stop location.
请注意,尽管使用了制表符而不是空格字符,但有些行在学生的名字和他们的数字分数之间仍然没有太多的空格。
这种差异是由于应用制表符间距的方式造成的。
制表符位置以四个字符的间隔设置,每个制表符将前进到下一个制表符位置。
如果你有一个五个字符的字符串,后面跟着一个制表符转义序列,转义序列将前进到八个字符位置的制表符,用空格字符填充空白,在输出中创建空白。但是,如果您有一个由七个字符组成的字符串,后跟一个制表符转义序列,则可以前进到相同的位置。
这中行为使得标签转义序列在距离下一个标签停止位置更远时更明显。
说明
原代码试图通过 \t
(tab) 制表符来对齐列,但 \t
的对齐并不总是精确的,特别是在字符串的长度不同或对齐方式不一致的情况下。
补全代码:
根据问题描述,变量 sophiaScore
, nicolasScore
, zahirahScore
, 和 jeongScore
应该先定义,并且给它们赋一个值。完整代码如下:
using System;
class Program
{
static void Main()
{
// 假设成绩的数值
double sophiaScore = 94.6;
double nicolasScore = 83.6;
double zahirahScore = 83.4;
double jeongScore = 95.4;
// 使用 \t 来对齐列
Console.WriteLine("Student\tGrade");
Console.WriteLine("Sophia:\t" + sophiaScore + "\tA");
Console.WriteLine("Nicolas:\t" + nicolasScore + "\tB");
Console.WriteLine("Zahirah:\t" + zahirahScore + "\tB");
Console.WriteLine("Jeong:\t" + jeongScore + "\tA");
}
}
输出如下
Student Grade
Sophia: 94.6 A
Nicolas: 83.6 B
Zahirah: 83.4 B
Jeong: 95.4 A
解释输出没有对齐的原因:
-
Tab 的间隔大小:
\t
(tab)会将光标定位到下一个制表符位置,而不是一个固定的字符数。因此,每当遇到\t
时,光标会跳到下一个“制表位”,通常是每隔 4 个字符(这取决于终端或控制台的设置)。这意味着,如果一个字符串的长度较短,\t
会跳得较远,导致在不同长度的字符串之间产生不一致的间隔。推测:如果制表符的设置为4个空白字符,那么对于
A\tB\tC
(其中A,B,C是三个字符串),可以保证A,B,C之间的空格数量为 1 , 2 , 3 , 4 {1,2,3,4} 1,2,3,4中的一个,不可能是0;比如A的字符串长度为 -
不同字符串长度的影响: 在输出中,我们有一些学生姓名和对应的分数,这些姓名和分数的长度各不相同。例如,“Sophia” 比 “Nicolas” 短,因此
\t
可能将它们对齐得不准确。在控制台输出时,当字符串的字符数不同,使用\t
可能不能精确对齐列。例如:-
“Sophia” 后面的
\t
会跳到下一个制表符位置,导致“94.6”与“A”之间有更大的间距。 -
而 “Nicolas” 后面加上
\t
会跳到另一个位置,导致相同位置的空白间隔不一致。
-
制表符行为实验👺
-
Console.WriteLine("1\t5678"); Console.WriteLine("12\t5678"); Console.WriteLine("123\t5678"); Console.WriteLine("1234\t5678"); Console.WriteLine("00001\t5678"); Console.WriteLine("000012\t5678"); Console.WriteLine("0000123\t5678"); Console.WriteLine("00001234\t5678");
输出(如果
\t
对应4个空格时)1 5678 12 5678 123 5678 1234 5678 00001 5678 000012 5678 0000123 5678 00001234 5678
-
如何解决:
- 固定宽度列:一种常见的做法是使用固定宽度格式(例如,使用
String.Format
或Console.WriteLine
的格式化字符串)来确保每列都有一致的宽度。 - 对齐方式:通过格式化输出,可以指定字段宽度、对齐方式等。例如,使用字符串插值时指定字段宽度,如下所示:
- 固定宽度列:一种常见的做法是使用固定宽度格式(例如,使用
改进后的代码
针对性对齐,使用格式化字符串对齐:
using System;
class Program
{
static void Main()
{
// 假设成绩的数值
double sophiaScore = 94.6;
double nicolasScore = 83.6;
double zahirahScore = 83.4;
double jeongScore = 95.4;
// 使用格式化字符串对齐输出
Console.WriteLine("{0,-10}\t{1,-6}", "Student", "Grade");
Console.WriteLine("{0,-10}\t{1,-6}\t{2}", "Sophia", sophiaScore, "A");
Console.WriteLine("{0,-10}\t{1,-6}\t{2}", "Nicolas", nicolasScore, "B");
Console.WriteLine("{0,-10}\t{1,-6}\t{2}", "Zahirah", zahirahScore, "B");
Console.WriteLine("{0,-10}\t{1,-6}\t{2}", "Jeong", jeongScore, "A");
}
}
格式化说明:
{0,-10}
表示第一个参数(名字)占用 10 个字符,左对齐(负号表示左对齐)。{1,-6}
表示第二个参数(成绩)占用 6 个字符,左对齐。{2}
表示第三个参数(成绩等级)会根据实际内容自动对齐。
输出:
Student Grade
Sophia 94.6 A
Nicolas 83.6 B
Zahirah 83.4 B
Jeong 95.4 A
这样,输出会更加整齐,每列都保持固定的宽度,从而确保数据的对齐。
总结:
- 为什么
\t
没有对齐:Tab
会将光标定位到下一个制表符位置,而不同长度的字符串会导致不同的跳跃,进而导致对齐不一致。 - 如何解决:使用格式化字符串(例如
{0,-10}
)来确保每列都有固定宽度,避免\t
造成的不一致问题。