C语言中水平制表符 t 与退格键 b 的使用方法探索

经个人实践,C语言中使用 t 会从下一个制表位开始继续输出,即会输出一个 8 个(32 位架构下 4 个,64 位架构下 8 个)格数的组合,当 t 之前的内容达到 8 * n 格时,后续内容出现在 8 * (n + 1) + 1 格。(式中 n >= 1,且为整数)
而使用 b 会根据 shell 的不同表现为:向左回退一格(常见)或删除一格。

探索过程如下:
第一次在看到某大佬的科普中提到:

b将输出位置左移一位

t表示一个tab的距离即1个大空格,相当于4个小空格

上述代码的理解:

  tbtb 表示前进四个空格然后回退一个空格,做两次相同操作,于是数字1会定位到数字7对应的位置下方。

  ttbb 表示前进两个大空格然后再回退两个大空格,即将t看成一个tab的效果,回退的是两个tab,所以最后回到最初位置,也就是数字0对应的位置下方。

  1. 但可能是文章时间久远,中间规范发生了变化,如今在个人的尝试下未能重现,代码如下:
int main() {
    printf("1234567890123456789012345678901234567890n");  //参考格数个位用
    printf("0        1         2         3         4n");  //参考格数十位用
    printf("tban");
    printf("tbtban");
    printf("tbtbtban");
    printf("tbtbtbtban");
    printf("ttbb1n");
    printf("tttbbb1n");
    printf("ttttbbbb1n");
    printf("tttttbbbbb1n");
    printf("0        1         2         3         4n");  //参考格数十位用
    printf("1234567890123456789012345678901234567890n");  //参考格数个位用
    return 0;
}

得到的结果是:

1234567890123456789012345678901234567890
0        1         2         3         4
       a
       a
       a
       a
              1
                     1
                            1
                                   1
0        1         2         3         4
1234567890123456789012345678901234567890

结果中无论一行中 tb 出现几次,内容 a 终会出现在第 8 格,而类 ttbb 的代码则会使内容 a 出现在 8 + 7 * n 格。结果明显不符合预期之后怀疑是 t 可能会在与其它转义序列码组合时发生变化,或者是可能会与前面内容的长度(格数)有关。

  1. 首先考虑是 t 可能会在与其它转义序列码组合时发生变化,因此进行了组合尝试,代码如下:
int main() {
    printf("12345678901234567890n");
    printf("0        1         2n");
    printf("tan");
    printf("ban");
    printf("tban");
    printf("1234tban");
    printf("12b34tban");
    printf("12b34tan");
    printf("12a34tban");
    printf("12ba34tban");
    printf("12ab34tban");
    printf("0        1         2n");
    printf("12345678901234567890n");
    return 0;
}

得到的结果是:

12345678901234567890
0        1         2
        a
a
       a
1234   a
134    a
134     a
1234   a
134    a
134    a
0        1         2
12345678901234567890

结果中如果不受 t 后的转义序列码影响,内容 a 终会出现在第 8 格。因此可知,t 后的内容并不会受到前面一部分的转义序列码影响。

  1. 既然前面猜想错误,那么就可能会与前面内容的长度(格数)有关,因此咋去除了一般 t 前后的 b 后进行了长度测试,代码如下:
int main() {
    printf("12345678901234567890n");
    printf("0        1         2n");
    printf("123456tan");
    printf("1234567tan");
    printf("12345678tan");
    printf("123456789tan");
    printf("1234567890tan");
    printf("123456789012345tan");
    printf("1234567890123456tan");
    printf("1234567890ta12tbn");
    printf("1234567890tbbbbbbba12tbn");
    printf("1234567890tbbbbbbbbbba12tbn");
    printf("1234567890bbbba12tbn");
    printf("0        1         2         3n");
    printf("123456789012345678901234567890n");
    return 0;
}

结果如下:

12345678901234567890
0        1         2
123456  a
1234567 a
12345678        a
123456789       a
1234567890      a
123456789012345 a
1234567890123456        a
1234567890      a12     b
123456789a12    b
123456a120      b
123456a120      b
0        1         2         3
123456789012345678901234567890

结果中可以发现,当第一个 t 前的内容少于 7 格时,内容 a 总会出现在第 9 格;当第一个 t 前的内容大于等于 8 格小于等于 15 格时内容 a 会出现在第 17 格,因此可以类比得出:t 会输出一个 8 个格数的组合,当 t 之前的内容达到 8 * n 格时,后续内容出现在 8 * (n + 1) + 1 格。

同时,根据最后三例结果:

123456789a12    b
123456a120      b
123456a120      b

可以得出:b 会删去该序列组合左侧的空格,遇到非空格的内容会对该格进行覆盖占用,并在继续向左占用后恢复右侧未占用格中的内容。

探索仍在继续,过程可能出现错误,如能指出则万分感谢!

千百度
© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容