2012-05-10 15 views
8

Necesito escribir diferentes párrafos de texto dentro de un área determinada. Por ejemplo, he dibujado un cuadro a la consola que tiene este aspecto:¿Ajustar el texto a la siguiente línea cuando excede cierta longitud?

/----------------------\ 
|      | 
|      | 
|      | 
|      | 
\----------------------/ 

¿Cómo voy a escribir un texto dentro de ella, pero se envuelve a la siguiente línea si se pone demasiado larga?

+3

¿Qué has probado? ¿Qué salió mal? –

+0

Supongo que no quieres dividir las palabras? –

+0

@ L.B Intenté leer la longitud de la cuerda y dividirla si excede el ancho de la caja, pero eso me obligaría a dividir las palabras. Y simplemente no parecía funcionar tan bien. –

Respuesta

10

¿Dividir en el último espacio antes de la longitud de la fila?

int myLimit = 10; 
string sentence = "this is a long sentence that needs splitting to fit"; 
string[] words = sentence.Split(new char[] { ' ' }); 
IList<string> sentenceParts = new List<string>(); 
sentenceParts.Add(string.Empty); 

int partCounter = 0; 

foreach (string word in words) 
{ 
    if ((sentenceParts[partCounter] + word).Length > myLimit) 
    { 
     partCounter++; 
     sentenceParts.Add(string.Empty); 
    } 

    sentenceParts[partCounter] += word + " "; 
} 

foreach (string x in sentenceParts) 
    Console.WriteLine(x); 

ACTUALIZACIÓN (la solución anterior perdió la última palabra en algunos casos):

int myLimit = 10; 
string sentence = "this is a long sentence that needs splitting to fit"; 
string[] words = sentence.Split(' '); 

StringBuilder newSentence = new StringBuilder(); 


string line = ""; 
foreach (string word in words) 
{ 
    if ((line + word).Length > myLimit) 
    { 
     newSentence.AppendLine(line); 
     line = ""; 
    } 

    line += string.Format("{0} ", word); 
} 

if (line.Length > 0) 
    newSentence.AppendLine(line); 

Console.WriteLine(newSentence.ToString()); 
+0

Eso tiene la posibilidad de dividir palabras a la mitad, lo que no quiero. –

+0

Algunos ejemplos estupendos [aquí] (http://stackoverflow.com/questions/4398270/how-to-split-string-preserving-whole-words) –

+1

No debe dividir las palabras por la mitad, porque solo agrega palabras completas hasta el límite de longitud es alcanzado. Sin embargo, sería mejor utilizar el objeto 'StringBuilder' para construir la línea final y usar el método' String.Format' de esta manera: 'String.Format (" {0} ", word);'. Usar el enumerador para la lista en lugar de obtener elementos por índices también sería bueno :). Esas actualizaciones pueden hacer que el código sea más eficiente, sin embargo, debería funcionar igual de bien. –

2

que modificó la versión de Jim H tal que soporta algunos casos especiales. Por ejemplo, el caso cuando la oración no contiene ningún carácter de espacio en blanco; También noté que hay un problema cuando una línea tiene un espacio en la última posición; luego, el espacio se agrega al final y terminas con un personaje demasiado.

Aquí está mi versión por si acaso a alguien le interesa:

public static List<string> WordWrap(string input, int maxCharacters) 
{ 
    List<string> lines = new List<string>(); 

    if (!input.Contains(" ")) 
    { 
     int start = 0; 
     while (start < input.Length) 
     { 
      lines.Add(input.Substring(start, Math.Min(maxCharacters, input.Length - start))); 
      start += maxCharacters; 
     } 
    } 
    else 
    { 
     string[] words = input.Split(' '); 

     string line = ""; 
     foreach (string word in words) 
     { 
      if ((line + word).Length > maxCharacters) 
      { 
       lines.Add(line.Trim()); 
       line = ""; 
      } 

      line += string.Format("{0} ", word); 
     } 

     if (line.Length > 0) 
     { 
      lines.Add(line.Trim()); 
     } 
    } 

    return lines; 
} 
2

he modificado la versión de Manfred. Si coloca una cadena con el carácter '\ n' en ella, envolverá el texto de forma extraña porque lo contará como otro carácter. Con este pequeño cambio todo irá sin problemas.

public static List<string> WordWrap(string input, int maxCharacters) 
    { 
     List<string> lines = new List<string>(); 

     if (!input.Contains(" ") && !input.Contains("\n")) 
     { 
      int start = 0; 
      while (start < input.Length) 
      { 
       lines.Add(input.Substring(start, Math.Min(maxCharacters, input.Length - start))); 
       start += maxCharacters; 
      } 
     } 
     else 
     { 
      string[] paragraphs = input.Split('\n'); 

      foreach (string paragraph in paragraphs) 
      { 
       string[] words = paragraph.Split(' '); 

       string line = ""; 
       foreach (string word in words) 
       { 
        if ((line + word).Length > maxCharacters) 
        { 
         lines.Add(line.Trim()); 
         line = ""; 
        } 

        line += string.Format("{0} ", word); 
       } 

       if (line.Length > 0) 
       { 
        lines.Add(line.Trim()); 
       } 
      } 
     } 
     return lines; 
    } 
1

Comencé con Jim H.'s solution y termino con este método. El único problema es si el texto tiene alguna palabra más larga que el límite. Pero funciona bien

public static List<string> GetWordGroups(string text, int limit) 
{ 
    var words = text.Split(new string[] { " ", "\r\n", "\n" }, StringSplitOptions.None); 

    List<string> wordList = new List<string>(); 

    string line = ""; 
    foreach (string word in words) 
    { 
     if (!string.IsNullOrWhiteSpace(word)) 
     { 
      var newLine = string.Join(" ", line, word).Trim(); 
      if (newLine.Length >= limit) 
      { 
       wordList.Add(line); 
       line = word; 
      } 
      else 
      { 
       line = newLine; 
      } 
     } 
    } 

    if (line.Length > 0) 
     wordList.Add(line); 

    return wordList; 
} 
Cuestiones relacionadas