2016-06-22 15 views
-2

In Ordnung, also in meinem Betriebssystem C# Cosmos arbeite ich an einem System, das es mir ermöglicht, eine Zeichenfolge und eine gewünschte Breite einzugeben und die Zeichenfolge basierend auf der Breite in Zeilen zu verpacken.Warum funktioniert dieser C# String-Wrapping-Algorithmus nicht?

Es funktioniert sorta wie folgt: Eingabe String ist "Hallo schöne Welt". Die Breite ist 6. Der Algorithmus wird durch die Zeichenfolge iterieren, und wenn der char-Index der Breite entspricht und das aktuelle Zeichen ein Leerzeichen ist, wird alles vom Anfang der Zeichenfolge bis zu diesem Punkt genommen, zu dem es hinzugefügt wird eine Liste, und entfernen Sie es aus der Zeichenfolge selbst und setzen Sie den Char-Index auf 0, und beginnen Sie neu. Dies geschieht, bis die Zeichenfolge entweder leer oder kleiner als die Breite ist. Wenn es kleiner als die Breite ist, wird es zur Liste hinzugefügt, und die for-Schleife wird beendet. In Laien sollten unsere Ausgabezeichenfolge kommen wie folgt aus:

Hallo
schöne
Welt.

Dies ist mein Code.

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; 
    } 

Die Sache ist die, manchmal, wenn ich mit der Zeichenfolge kleiner ist als die Breite behandeln am Ende mit, bekommen wir Probleme. Es scheint diesen Teil der Zeichenfolge zu überspringen. Huch!

Zum Beispiel ist hier ein Teil meines Betriebssystems, das dies verwendet. Es soll einen Titel und eine Nachricht aufnehmen und in einer Nachrichtenbox mit einer OK-Schaltfläche anzeigen.

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 
      { 

      } 
     } 
    } 

Ziemlich einfach. Beginnt mit einer Standardbreite von 25 Zeichen, und wenn der Titel größer ist, wird er auf die Titellänge gesetzt. Wenn die Textlänge kleiner als die Breite ist, wird die Breite zur Kompensation eingestellt. Dann macht es den Aufruf des Splitter-Algorithmus von oben, der in 'TUI.Utils' zu finden ist, und macht dann ein paar Dinge auf dem Bildschirm auszudrucken.

Hier ist ein Stück von meinem "ConfigurationManager" OS, eine Anwendung, die Benutzereingaben aufnimmt und verwendet, um eine Konfigurationsdatei zu generieren. Sehr gerade in Arbeit.

    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."); 

Aber haben wir einen Blick auf das LCD-Display kommt auf ...

The messagebox coming out of the above method call

Wie Sie sehen können, nicht wirklich das, was ich will. Es fehlt etwas von der Schnur!

+0

Sie müssen nur sehen, ob es eine Zeichenfolge ist am Ende übrig y unsere Schleife und füge den Rest (falls vorhanden) zur Liste hinzu. – itsme86

Antwort

2

Sie müssen text nicht ändern, da wir nur den Offset unserer ursprünglichen Teilzeichenfolge speichern können. Je weniger String-Manipulationen wir machen, desto besser.

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; 
} 

Testing:

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."); 

Gibt:

 
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.") 

Gibt

 
Hello 
beautiful 
world. 
+0

Okay. Mal sehen, ob dieser Algorithmus in Cosmos funktioniert.Wenn es so ist, weiß ich nicht, wie ich Ihnen danken kann, da ich nicht weiß, wie ich etwas als Antwort xD markieren soll –