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

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个小空格

上述代码的理解:

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

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

但可能是文章时间久远,中间规范发生了变化,如今在个人的尝试下未能重现,代码如下:

int main() {

printf("1234567890123456789012345678901234567890\n"); //参考格数个位用

printf("0 1 2 3 4\n"); //参考格数十位用

printf("\t\ba\n");

printf("\t\b\t\ba\n");

printf("\t\b\t\b\t\ba\n");

printf("\t\b\t\b\t\b\t\ba\n");

printf("\t\t\b\b1\n");

printf("\t\t\t\b\b\b1\n");

printf("\t\t\t\t\b\b\b\b1\n");

printf("\t\t\t\t\t\b\b\b\b\b1\n");

printf("0 1 2 3 4\n"); //参考格数十位用

printf("1234567890123456789012345678901234567890\n"); //参考格数个位用

return 0;

}

得到的结果是:

1234567890123456789012345678901234567890

0 1 2 3 4

a

a

a

a

1

1

1

1

0 1 2 3 4

1234567890123456789012345678901234567890

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

首先考虑是 \t 可能会在与其它转义序列码组合时发生变化,因此进行了组合尝试,代码如下:

int main() {

printf("12345678901234567890\n");

printf("0 1 2\n");

printf("\ta\n");

printf("\ba\n");

printf("\t\ba\n");

printf("1234\t\ba\n");

printf("12\b34\t\ba\n");

printf("12\b34\ta\n");

printf("12\a34\t\ba\n");

printf("12\b\a34\t\ba\n");

printf("12\a\b34\t\ba\n");

printf("0 1 2\n");

printf("12345678901234567890\n");

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 后的内容并不会受到前面一部分的转义序列码影响。

既然前面猜想错误,那么就可能会与前面内容的长度(格数)有关,因此咋去除了一般 \t 前后的 \b 后进行了长度测试,代码如下:

int main() {

printf("12345678901234567890\n");

printf("0 1 2\n");

printf("123456\ta\n");

printf("1234567\ta\n");

printf("12345678\ta\n");

printf("123456789\ta\n");

printf("1234567890\ta\n");

printf("123456789012345\ta\n");

printf("1234567890123456\ta\n");

printf("1234567890\ta12\tb\n");

printf("1234567890\t\b\b\b\b\b\b\ba12\tb\n");

printf("1234567890\t\b\b\b\b\b\b\b\b\b\ba12\tb\n");

printf("1234567890\b\b\b\ba12\tb\n");

printf("0 1 2 3\n");

printf("123456789012345678901234567890\n");

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 会删去该序列组合左侧的空格,遇到非空格的内容会对该格进行覆盖占用,并在继续向左占用后恢复右侧未占用格中的内容。

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

相关数据

使用蓝/绿部署方法部署 Amazon ECS 服务
365bet首页

使用蓝/绿部署方法部署 Amazon ECS 服务

⌛ 08-10 👁️‍🗨️ 7181
荒野行动怎么切换视角或切换第三人称视角
bat365在线平台用户官网

荒野行动怎么切换视角或切换第三人称视角

⌛ 10-07 👁️‍🗨️ 566
《地藏经》回向文大全,建议收藏!
365bet首页

《地藏经》回向文大全,建议收藏!

⌛ 11-03 👁️‍🗨️ 3655
矶竿、前打杆、中通杆的比较!
bat365在线平台用户官网

矶竿、前打杆、中通杆的比较!

⌛ 09-17 👁️‍🗨️ 1803
叶脉书签的详细做法步骤图解教程 sc-guoqing作品
365bet世界

叶脉书签的详细做法步骤图解教程 sc-guoqing作品

⌛ 07-31 👁️‍🗨️ 3777