Here’s a class I wrote that will write with wordwrap to standard out in a .NET console app. There are a few other nifty options.
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
namespace McKinley
{
public sealed class Out
{
[StructLayout(LayoutKind.Sequential)]
private struct COORD
{
public short X;
public short Y;
}
[StructLayout(LayoutKind.Sequential)]
private struct CONSOLE_SCREEN_BUFFER_INFO
{
public COORD dwSize;
public COORD dwCursorPosition;
public short wAttributes;
public SMALL_RECT srWindow;
public COORD dwMaximumWindowSize;
}
[StructLayout(LayoutKind.Sequential)]
private struct SMALL_RECT
{
public short Left;
public short Top;
public short Right;
public short Bottom;
}
private const int STD_OUTPUT_HANDLE = -11;
[DllImport("kernel32.dll")]
private static extern IntPtr GetConsoleWindow();
[DllImport("kernel32.dll")]
private static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput,
out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(int nStdHandle);
private static CONSOLE_SCREEN_BUFFER_INFO StdOutInfo()
{
IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if(hOut != IntPtr.Zero)
{
CONSOLE_SCREEN_BUFFER_INFO info;
if(GetConsoleScreenBufferInfo(hOut, out info))
{
return info;
}
}
return new CONSOLE_SCREEN_BUFFER_INFO();
}
private static Point GetCursorPosition()
{
CONSOLE_SCREEN_BUFFER_INFO info = StdOutInfo();
return new Point(info.dwCursorPosition.X, info.dwCursorPosition.Y);
}
private static Point GetConsoleWindowSize()
{
CONSOLE_SCREEN_BUFFER_INFO info = StdOutInfo();
return new Point(info.dwSize.X, info.dwSize.Y);
}
/// <summary>
/// Writes <paramref name="val" /> to standard output with word wrap.
/// Each line is indented by <paramref name="indent" /> characters,
/// and is prefixed by the string specified by <paramref name="prefix"/>.
/// </summary>
public static void WordWrap(string val, int indent, string prefix)
{
int max = (GetConsoleWindowSize()).X;
string pad = new string(' ', indent)+prefix;
Regex r = new Regex(@"([\w\.]*(\s)?)");
Match words = r.Match(val);
int count = (GetCursorPosition()).X;
if(count == 0)
{
Console.Write(pad);
}
else
{
Console.Write(prefix);
}
count = (GetCursorPosition()).X;
while(words.Success)
{
string word = words.Value;
count += word.Length;
if(count >= max-1)
{
Console.WriteLine();
Console.Write(pad);
count = word.Length + pad.Length;
}
Console.Write(word);
words = words.NextMatch();
}
}
/// <summary>
/// Writes <paramref name="val"/> to the standard output
/// with word wrap. Each line is indented by
/// <paramref name="indent"/> characters.
/// </summary>
public static void WordWrap(string val, int indent)
{
WordWrap(val, indent, string.Empty);
}
/// <summary>
/// Writes <paramref name="val"/> to the standard output
/// with word wrap.
/// </summary>
public static void WordWrap(string val)
{
WordWrap(val,0);
}
private Out() { }
}
}