John NoCookies
John NoCookies

Reputation: 1061

Splitting text into lines with maximum length

I have a long string and I want to fit that in a small field. To achieve that, I break the string into lines on whitespace. The algorithm goes like this:

    public static string BreakLine(string text, int maxCharsInLine)
    {
        int charsInLine = 0;
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < text.Length; i++)
        {
            char c = text[i];
            builder.Append(c);
            charsInLine++;

            if (charsInLine >= maxCharsInLine && char.IsWhiteSpace(c))
            {
                builder.AppendLine();
                charsInLine = 0;
            }
        }
        return builder.ToString();
    }

But this breaks when there's a short word, followed by a longer word. "foo howcomputerwork" with a max length of 16 doesn't break, but I want it to. One thought I has was looking forward to see where the next whitespace occurs, but I'm not sure whether that would result in the fewest lines possible.

Upvotes: 7

Views: 7505

Answers (3)

nitin157
nitin157

Reputation: 51

update a code a bit, the @dead.rabit goes to loop sometime.

 public static string SplitToLines(string text,char[] splitanyOf, int maxStringLength)
    {               
        var sb = new System.Text.StringBuilder();
        var index = 0;
        var loop = 0;
        while (text.Length > index)
        {
            // start a new line, unless we've just started
            if (loop != 0)
            {
                sb.AppendLine();
            }

            // get the next substring, else the rest of the string if remainder is shorter than `maxStringLength`
            var splitAt = 0;
            if (index + maxStringLength <= text.Length)
            {
                splitAt = text.Substring(index, maxStringLength).LastIndexOfAny(splitanyOf);
            }
            else
            {
                splitAt = text.Length - index;
            }

            // if can't find split location, take `maxStringLength` characters
            if (splitAt == -1 || splitAt == 0)
            {
                splitAt = text.IndexOfAny(splitanyOf, maxStringLength);
            }

            // add result to collection & increment index
            sb.Append(text.Substring(index, splitAt).Trim());
            if(text.Length > splitAt)
            {
                text = text.Substring(splitAt + 1).Trim();
            }
            else
            {
                text = string.Empty;
            }
            loop = loop + 1;
        }

        return sb.ToString();
    }

Upvotes: 1

Dead.Rabit
Dead.Rabit

Reputation: 1975

Enjoy!

public static string SplitToLines(string text, char[] splitOnCharacters, int maxStringLength)
{
    var sb = new StringBuilder();
    var index = 0;

    while (text.Length > index)
    {
        // start a new line, unless we've just started
        if (index != 0)
            sb.AppendLine();

        // get the next substring, else the rest of the string if remainder is shorter than `maxStringLength`
        var splitAt = index + maxStringLength <= text.Length
            ? text.Substring(index, maxStringLength).LastIndexOfAny(splitOnCharacters)
            : text.Length - index;

        // if can't find split location, take `maxStringLength` characters
        splitAt = (splitAt == -1) ? maxStringLength : splitAt;

        // add result to collection & increment index
        sb.Append(text.Substring(index, splitAt).Trim());
        index += splitAt;
    }

    return sb.ToString();
}

Note that splitOnCharacters and maxStringLength could be saved in user settings area of the app.

Upvotes: 6

Moop
Moop

Reputation: 3611

Check the contents of the character before writing to the string builder and or it with the current count:

    public static string BreakLine(string text, int maxCharsInLine)
    {
        int charsInLine = 0;
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < text.Length; i++)
        {
            char c = text[i];
            if (char.IsWhiteSpace(c) || charsInLine >= maxCharsInLine)
            {
                builder.AppendLine();
                charsInLine = 0;
            }
            else 
            {
                builder.Append(c);
                charsInLine++;                    
            }
        }
        return builder.ToString();
    }

Upvotes: 1

Related Questions