C#使用换行格式化固定列宽的文本

时间:2016-03-01 18:17:53

标签: c#

我到处寻找并没有看到这个特定问题的答案...我正在用C#编写一个Windows控制台应用程序,并希望获取一组字符串并将它们格式化为固定宽度包装的列。返回的字符串应填充空格,并在每行末尾添加换行符。

这是一个例子。我有3个文本字符串,我想将它们装入包含3个固定宽度的列中。

string text10 = "abcdefghij";
string text15 = "123456789012345";
string text6 = "zxywvu";

我想将其格式化为3列,宽度为4 - 10 - 5(它们之间有空格)。举个例子:

format(text10, test15, text5)

会返回这个:

abcd 1234567890 zxywv\n
efgh 13245      u    \n
ij                   \n

有没有人知道使用.Net库执行此操作的简单方法,或者我是否必须为此内容编写文本格式化函数?

3 个答案:

答案 0 :(得分:1)

以下是使用LINQ的另一种方法:

string format(string column1, string column2, string column3)
    {
        int column1Width = 4;
        int column2Width = 10;
        int column3Width = 5;
        int loopCount = 0;

        StringBuilder output = new StringBuilder();

        while (true)
        {
            string col1 = new string(column1.Skip<char>(loopCount * column1Width).Take<char>(column1Width).ToArray()).PadRight(column1Width);
            string col2 = new string(column2.Skip<char>(loopCount * column2Width).Take<char>(column2Width).ToArray()).PadRight(column2Width);
            string col3 = new string(column3.Skip<char>(loopCount * column3Width).Take<char>(column3Width).ToArray()).PadRight(column3Width);

            //Break out of loop once all col variables contain only white space
            if (String.IsNullOrWhiteSpace(col1) && String.IsNullOrWhiteSpace(col2) && String.IsNullOrWhiteSpace(col3))
            {
                break;
            }

            output.AppendFormat("{0} {1} {2}\n", col1, col2, col3);
            loopCount++;
        }
        return output.ToString();
    }

答案 1 :(得分:0)

这是一种方法:

string format(string col1, string col2, string col3)
{
    var sb = new StringBuilder();
    while(col1.Length > 4 || col2.Length > 10 || col3.Length > 5)
    {
        sb.AppendLine(CreateLine(ref col1, ref col2, ref col3));
    }
    return sb.ToString();
}

string CreateLine(ref string col1, ref string col2, ref string col3)
{
    var returnValue = string.Format("{0} {1} {2}", 
                            col1.Substring(0, Math.Min(col1.Length, 4)).PadRight(4), 
                            col2.Substring(0, Math.Min(col2.Length, 10)).PadRight(10), 
                            col3.Substring(0, Math.Min(col3.Length, 5)).PadRight(5));
    if (col1.Length > 4) 
        col1 = col1.Substring(4, col1.Length - 4);
    if (col2.Length > 10) 
        col2 = col2.Substring(10, col2.Length - 10);
    if(col3.Length > 5)
        col3 = col3.Substring(5, col3.Length - 5);
    return returnValue;
}

备注:
要正确显示,你必须使用像miriam固定的等宽字体 2.如果要在浏览器上使用此功能,则需要使用&nbps而不是空格或使用<pre>标记包装结果。

答案 2 :(得分:0)

这正是那种与程序员有很多答案的问题。所以我也想尝试一下!如果您需要更改列的宽度或事件的数量,这样的事情怎么样?

    public static string PopFrontPadded(ref string oStr, int iPadding)
    {

        // Argument check
        if (iPadding <= 0)
            throw new ArgumentException("iPadding <= 0");

        // Handle idiots
        if (oStr == null)
            return "".PadRight(iPadding);

        // Pop front & pad
        string oRes = new string(oStr.Take(Math.Min(oStr.Length, iPadding)).ToArray());
        oStr = oStr.Substring(oRes.Length);
        return oRes.PadRight(iPadding);
    }

    public static string format(string oSeparator, string oNewLine, string[] oStrings, int[] oWidths)
    {

        // Null checks
        if (oStrings == null || oWidths == null || oSeparator == null || oNewLine == null)
            throw new ArgumentException("oStrings == null || oWidths == null || oSeparator == null || oNewLine == null");

        // Length check: Must be same amount of widths as there are strings
        if (oStrings.Length != oWidths.Length)
            throw new ArgumentException("oStrings.Length != oWidths.Length");

        // All widths must be > 0
        foreach (int i in oWidths)
        {
            if (i <= 0)
                throw new ArgumentException("width must be > 0");
        }


        var sb = new System.Text.StringBuilder();
        List<string> oList = new List<string>(oStrings);

        // Loop while oList contains even one string with length > 0
        do
        {
            // For all given strings
            for (int i = 0; i < oList.Count; i++)
            {

                // PopFrontPadded
                string oTmp = oList[i];
                sb.Append(PopFrontPadded(ref oTmp, oWidths[i]));
                oList[i] = oTmp;

                // Append separator
                if (i < oList.Count - 1)
                    sb.Append(oSeparator);
            }

            // Append New Line
            sb.Append(oNewLine);

        } 
        while (oList.Find(x => x.Length > 0) != null); 

        return sb.ToString();
    }

    [STAThread]
    static void Main()
    {
        string text10 = "abcdefghij";
        string text15 = "123456789012345";
        string text6 = "zxywvu";

        string oResult = format(
            " ",                                      // Separator
            Environment.NewLine,                      // Line break
            new string[3] { text10, text15, text6 },  // strings
            new int[3]    {      4,     10,     5 }); // column widths

        Console.WriteLine(oResult);
        /* Outputs 
         *
         * abcd 1234567890 zxywv
         * efgh 12345      u    
         * ij                                
         *
         */
    }