当前位置: 首页 > article >正文

编程语言中制表符的打印和输出@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=nr= 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 43=1,也就是字符串A和B之间的间隔是1个空格

如果上述结论是对的话,那么

  • 设置制表符对应的空格数大一些,可以更大的几率让表格数据各行各列对齐
  • 在适当的位置连续使用多个制表符
  • 使用固定字段长度的输出控制实现整齐输出

输出带有制表符的字符串的对齐问题

C#为例

练习 - 使用转义字符序列设置输出格式 - Training | Microsoft Learn

  1. 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.

  2. To view the results of your updates, select Run.

  3. 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
    
  4. 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

解释输出没有对齐的原因:

  1. 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的字符串长度为

  2. 不同字符串长度的影响: 在输出中,我们有一些学生姓名和对应的分数,这些姓名和分数的长度各不相同。例如,“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
    
  1. 如何解决

    • 固定宽度列:一种常见的做法是使用固定宽度格式(例如,使用 String.FormatConsole.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 造成的不一致问题。

http://www.kler.cn/a/532917.html

相关文章:

  • JavaScript系列(57)--工程化实践详解
  • 多线程的常用方法
  • ubuntu22.40安装及配置静态ip解决重启后配置失效
  • Vue3学习笔记-模板语法和属性绑定-2
  • Cmake学习笔记
  • 在 Ubuntu 中使用 Conda 创建和管理虚拟环境
  • 人类心智逆向工程:AGI的认知科学基础
  • 04树 + 堆 + 优先队列 + 图(D1_树(D15_哈夫曼树/霍夫曼树))
  • 算法与数据结构(合并有序链表)
  • Vue.js 如何选择合适的组件库
  • Spring PropertyPlaceholderConfigurer多配置问题
  • Verilog基础(三):过程
  • INA226的初次使用
  • Java基础学习笔记-标识符、变量、常量、关键字
  • 【C++】Lambda表达式
  • Linux 文件和目录
  • 图像增广:用OpenCV实现的6个自动图像增强策略
  • 【数据分析】豆瓣电影Top250的数据分析与Web网页可视化(numpy+pandas+matplotlib+flask)
  • UE求职Demo开发日志#19 给物品找图标,实现装备增加属性,背包栏UI显示装备
  • ip属地是根据所在位置定位的吗
  • C#中的委托(Delegate)
  • Redis-BitMap实现签到功能
  • 2024美团春招硬件开发笔试真题及答案解析
  • JVM 四虚拟机栈
  • 暴力破解与验证码安全
  • LabVIEW涡轮诊断系统