經個人實踐,C語言中使用轉義序列碼(\t)會輸出一個 8 個格數的組合,當 \t 之前的內容達到 8 * n 格時,後續內容出現在 8 * (n + 1) + 1 格。(式中 n >= 1,且為整數)
探索過程如下:
第一次在看到某大佬的科普中提到:
\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 會刪去該序列組合左側的空格,遇到非空格的內容會對該格進行覆蓋佔用,並在繼續向左佔用後恢復右側未佔用格中的內容。
探索仍在繼續,過程可能出現錯誤,如能指出則萬分感謝!