-3

さて、私の C# Cosmos オペレーティング システムでは、文字列と目的の幅を入力し、幅に基づいて文字列を行に折り返すシステムに取り組んでいます。

次のように機能します。入力文字列は「Hello beautiful world」です。幅は 6 です。アルゴリズムは文字列を反復処理し、文字インデックスが幅のインデックスであり、現在の文字がスペースである場合、文字列の先頭からそのポイントまでのすべてを取得し、それをList を取得し、それを文字列自体から削除し、char インデックスを 0 にリセットして、最初からやり直します。文字列が空になるか、幅より小さくなるまでこれを行います。幅よりも小さい場合は、リストに追加され、for ループが終了します。一般的に言えば、出力文字列は次のようになります。

こんにちは
美しい
世界。

これは私のコードです。

public static List<string> split_string(int width, string text)
    {
        List<string> text_lines = new List<string>();
        //Separate lines of text.
        for (int i = 0; i < text.Length; i++)
        {
            if (text.Length <= width)
            {
                text_lines.Add(text);
                i = text.Length + 5;
            }
            else
            {
                if (i >= width)
                {
                    if (text[i] == ' ')
                    {
                        text_lines.Add(text.Substring(0, i + 1));
                        text = text.Remove(0, i + 1);
                        i = 0;
                    }
                }
            }
        }
        return text_lines;
    }

問題は、文字列が幅よりも小さいことに対処しなければならない場合、問題が発生することがあります。文字列のその部分をスキップしているようです。うわぁ!

たとえば、これを使用する私の OS の一部を次に示します。タイトルとメッセージを受け取り、OK ボタンのあるメッセージボックスに表示することになっています。

public static void ShowMessagebox(string title, string text)
    {
        int splitWidth = 25;
        if(text.Length < splitWidth)
        {
            splitWidth = text.Length;
        }
        if(title.Length > splitWidth)
        {
            splitWidth = title.Length;
        }
        var lines = new List<string>();
        if(splitWidth > text.Length)
        {
            lines.Add(text);
        }
        else
        {
            lines = TUI.Utils.split_string(splitWidth, text);
        }
        foreach(var line in lines)
        {
            if(text.Contains(line))
            {
                text = text.Replace(line, "");
            }
        }
        if(text.Length > 0)
        {
            lines.Add(text);
        }
        int h = lines.Count + 4;
        int w = 0;
        foreach(var line in lines)
        {
            if(line.Length + 4 > w)
            {
                w = line.Length + 4;
            }
        }
        int x = (Console.WindowWidth - w) / 2;
        int y = (Console.WindowHeight - h) / 2;
        TUI.Utils.ClearArea(x, y, w, h, ConsoleColor.Green);
        TUI.Utils.ClearArea(x, y, w, 1, ConsoleColor.White);
        TUI.Utils.Write(x + 1, y, title, ConsoleColor.White, ConsoleColor.Black);
        for(int i = 0; i < lines.Count - 1; i++)
        {
            TUI.Utils.Write(x + 2, (y + 2) + i, lines[i], ConsoleColor.Green, ConsoleColor.White);
        }
        int xw = x + w;
        int yh = y + h;
        TUI.Utils.Write(xw - 6, yh - 2, "<OK>", TUI.Utils.COL_BUTTON_SELECTED, TUI.Utils.COL_BUTTON_TEXT);
        bool stuck = true;
        while (stuck)
        {
            var kinf = Console.ReadKey();
            if (kinf.Key == ConsoleKey.Enter)
            {
                stuck = false;
                Console.Clear();
            }
            else
            {

            }
        }
    }

ものすごく単純。デフォルトの幅 25 文字で開始し、タイトルがそれより大きい場合は、タイトルの長さに設定します。テキストの長さが幅よりも小さい場合、幅を補正するように設定します。次に、「TUI.Utils」にある上記のスプリッター アルゴリズムを呼び出し、画面に出力する処理を行います。

これは、ユーザー入力を受け取り、それを使用して構成ファイルを生成するアプリケーションである、私の OS の「ConfigurationManager」の一部です。現在非常に進行中です。

                    Curse.ShowMessagebox("Memphis can't run properly this system.", "Memphis needs at least one FAT partition on a Master Boot Record to be able to store it's configuration and other files on. Please use a partition utility like GParted to partition your hard drive properly.");

しかし、私の画面に出てくるものを見てください...

上記のメソッド呼び出しから出てくるメッセージボックス

ご覧のとおり、私が本当に欲しいものではありません。紐の一部が欠けています!

4

1 に答える 1