Console.WriteLine with Wordwrap
May 17th, 2005
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() { } } }