2016-06-22 68 views
-2

好吧,在我的C#Cosmos操作系统中,我正在开发一个系统,该系统可以输入字符串和所需的宽度,并根据宽度将字符串包装成行。为什么这个c#字符串包装算法不起作用?

它的工作原理类似于:输入字符串是“你好美丽的世界”。宽度为6.算法将循环遍历字符串,如果char索引是宽度,并且当前字符是空格,它将从字符串的开头直到该点的所有内容,将其添加到一个List,并将其从字符串本身中移除,并将char索引重置为0,然后重新开始。它会这样做直到字符串为空或小于宽度。如果它小于宽度,则将其添加到List中,并且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; 
    } 

事情是,有时,如果我最终不得不处理小于宽度的字符串,我们会遇到问题。它似乎跳过了那部分字符串。哎呀!

例如,这是我的一个操作系统,它使用了这个。它应该采用标题和消息,并使用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'中找到,然后做一些东西打印到屏幕上。

这是我的操作系统的一个“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."); 

但是看看出什么来在我的屏幕...

The messagebox coming out of the above method call

正如你所看到的,不是我真正想要的东西。它缺少一些字符串!

+0

你只需要看看是否有在年底遗留任何字符串ÿ我们的循环并将其余部分(如果有的话)添加到列表中。 – itsme86

回答

2

您不需要更改text,因为我们可以存储原始子字符串的偏移量。我们做的字符串操作越少越好。

public static List<string> split_string(int width, string text) 
{ 
    width = width - 1; //So we're not constantly comparing to width - 1 
    var returnSet = new List<string>(); 
    var currLength = 0; 
    var oldOffset = 0; 
    for (var i = 0; i < text.Length; i++) 
    { 
     if (currLength >= width && text[i] == ' ') 
     { 
      returnSet.Add(text.Substring(oldOffset, i - oldOffset)); 
      oldOffset = i + 1; 
      currLength = 0; 
      continue; 
     } 
     currLength++; 
    } 
    if (oldOffset < text.Length) 
     returnSet.Add(text.Substring(oldOffset)); 

    return returnSet; 
} 

测试:

split_string(25, "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."); 

给出:

 
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. 
split_string(6, "Hello beautiful world.") 

给人

 
Hello 
beautiful 
world. 
+0

好的。我们来看看这个算法是否可以在Cosmos中运行。如果是这样,那么我不知道该如何感谢你,因为我不知道如何标记某个答案为xD –