產生文字檔或顯示純文字時會蠻常遇到類似:呈現多欄資料,文字靠左,數字靠右,每一欄寬度固定,字串長度不足時補空白至指定寬度。(例如下面這個例子)

分享我以前的笨寫法 - 自己寫一個輸出固定長度字串的函數,傳入字串(或數值)、欄位寬度並指定左靠或右靠,函數負責補足空白:

class Program
{
    static string FixedWidth(object value, int width, bool leftAlign)
    {
        var s = value == null ? string.Empty : value.ToString();
        return leftAlign ? s.PadRight(width) : s.PadLeft(width);
    }

    class Entry
    {
        public string Name;
        public int Score;

    }

    static void Main(string[] args)
    {
        var data = new List<Entry>
        {
            new Entry { Name = "Jeffrey", Score = 32767 },
            new Entry { Name = "Fox", Score = 255},
            new Entry { Name = "Darkthread", Score = 9999}
        };
        data.ForEach(o =>
        {
            Console.WriteLine(
                $"{FixedWidth(o.Name, 16, true)} {FixedWidth(o.Score.ToString("N0"), 6, false)}");
        });
    }
}

程式看起來沒什麼問題,結果也正確,笨點在哪?

.NET string.Format() 本身就有補空白跟左右對齊功能啊! 幹嘛自己寫?

一直以來,我以為 string.Format() 的格式標示只有 {0} 或 {0:X} 兩種,其實它的完整語法是 {index[,alignment][:formatString]},alignment 可填入整數指定寬度,正數是左補空白,負數為右補空白,字串會補成固定長度達到上下對齊的效果。官方文件

學會字串插值之後,我已很少再寫 string.Format 了,$"..." 也可以適用這種格式寫法嗎?沒問題,$"{strVar,-16} {intVar, 8:N0}",把 index 換成變數名,其餘不變。

所以,上面程式可以省略自訂函數,寫成:(範例有一併列出 Console.WriteLine 的三種寫法,但是都 9102 年了,就用 $"..." 吧!)

data.ForEach(o =>
{
	//格式字串規則 {index[,alignment][:formatString]}  
	//Console.WriteLine(string.Format("{0,-16} {1,6:N0}", o.Name, o.Score));
	//Console.WriteLine("{0,-16} {1,6:N0}", o.Name, o.Score);
	Console.WriteLine(
		$"{o.Name, -16} {o.Score, 6:N0}");
});

分享給跟我一樣不知 string.Format() 可以補空白成固定長度的同學。

補充:經讀者 SY H 提醒,忘了說明以上技巧主要適用英數字。中文或中英文混雜的固定欄寬是另一門學問,請參考舊文:

  1. TIPS-固定欄寬資料檔的解析
  2. TIPS-製作固定欄寬資料檔

Tips of using string.Format() or interpolated strings to pad spaces and align text.


Comments

# by SY H

然後你會開始研究為什麼字串裡有中文會無法對齊

# by Jeffrey

to SY H, 謝謝提醒,忘了提中文的事,己補充於內文。

# by Jichen

String我都用padleft或padright來補足長度

Post a comment


69 + 31 =