C# 控制台换行

C# 控制台换行,c#,console-application,C#,Console Application,我有一个带换行符的字符串,我想把单词包装起来。我想保留换行符,这样当我显示文本时,它看起来像是单独的段落。有人有很好的功能来做这件事吗?下面是当前函数和代码。不是我自己的函数。WordWrap函数似乎正在剥离\n个字符 static void Main(string[] args){ StreamReader streamReader = new StreamReader("E:/Adventure Story/Intro.txt"); string intr

我有一个带换行符的字符串,我想把单词包装起来。我想保留换行符,这样当我显示文本时,它看起来像是单独的段落。有人有很好的功能来做这件事吗?下面是当前函数和代码。不是我自己的函数。WordWrap函数似乎正在剥离\n个字符

static void Main(string[] args){

        StreamReader streamReader = new StreamReader("E:/Adventure Story/Intro.txt");

        string intro = "";
        string line;

        while ((line = streamReader.ReadLine()) != null)
        {
            intro += line;
            if(line == "")
            {
                intro += "\n\n";
            }
        } 
        WordWrap(intro);

public static void WordWrap(string paragraph)
    {
        paragraph = new Regex(@" {2,}").Replace(paragraph.Trim(), @" ");
        var left = Console.CursorLeft; var top = Console.CursorTop; var lines = new List<string>();
        for (var i = 0; paragraph.Length > 0; i++)
        {
            lines.Add(paragraph.Substring(0, Math.Min(Console.WindowWidth, paragraph.Length)));
            var length = lines[i].LastIndexOf(" ", StringComparison.Ordinal);
            if (length > 0) lines[i] = lines[i].Remove(length);
            paragraph = paragraph.Substring(Math.Min(lines[i].Length + 1, paragraph.Length));
            Console.SetCursorPosition(left, top + i); Console.WriteLine(lines[i]);
        }
    }

若您希望另一个换行符使文本看起来像段落,只需使用字符串对象的Replace方法

        var str =
            "Line 1\n" +
            "Line 2\n" +
            "Line 3\n";

        Console.WriteLine("Before:\n" + str);

        str = str.Replace("\n", "\n\n");

        Console.WriteLine("After:\n" + str);

下面是一个单词换行函数,它使用正则表达式查找可以中断的位置和必须中断的位置。然后,它返回基于中断区域的原始文本片段。它甚至允许在连字符和其他字符处中断,而不删除连字符,因为正则表达式使用零宽度正向前瞻断言

    IEnumerable<string> WordWrap(string text, int width)
    {
        const string forcedBreakZonePattern = @"\n";
        const string normalBreakZonePattern = @"\s+|(?<=[-,.;])|$";

        var forcedZones = Regex.Matches(text, forcedBreakZonePattern).Cast<Match>().ToList();
        var normalZones = Regex.Matches(text, normalBreakZonePattern).Cast<Match>().ToList();

        int start = 0;

        while (start < text.Length)
        {
            var zone = 
                forcedZones.Find(z => z.Index >= start && z.Index <= start + width) ??
                normalZones.FindLast(z => z.Index >= start && z.Index <= start + width);

            if (zone == null)
            {
                yield return text.Substring(start, width);
                start += width;
            }
            else
            {
                yield return text.Substring(start, zone.Index - start);
                start = zone.Index + zone.Length;
            }
        }
    }

最近,我一直在致力于创建一些抽象,在性能和内存敏感的控制台上下文中模拟类似窗口的特性

为此,我必须在没有任何不必要的字符串分配的情况下实现单词包装功能

以下是我设法将其简化为的内容。此方法:

保留输入字符串中的新行, 允许您指定它应该在空格、连字符等上打断哪些字符。, 通过Microsoft.Extensions.Primitives.StringSegment结构实例返回行的起始索引和长度,但用自己的结构替换此结构或直接附加到StringBuilder非常简单。 公共静态IEnumerable WordWrapsString输入,int maxLineLength,char[]breakableCharacters { int lastBreakIndex=0; 虽然是真的 { var nextForcedLineBreak=lastBreakIndex+maxLineLength; //如果余数小于允许的行长度,则返回余数。对于小于行长度的字符串,立即短路。 如果nextForcedLineBreak>=输入.Length { 返回新StringSegmentinput、lastBreakIndex、input.Length-lastBreakIndex; 屈服断裂; } //如果在下一个强制中断位置之前有本机新行,请使用最后一个本机新行作为下一行的起始位置。 int nativeNewlineIndex=input.LastIndexOfEnvironment.NewLine,nextForcedLineBreak,maxLineLength; 如果nativeNewlineIndex>-1 { nextForcedLineBreak=nativeNewlineIndex+Environment.NewLine.Length+maxLineLength; } //找到下一个强制打断位置之前的最后一个可打断点,并包含可打断角色,该角色可能是催眠。 var nextbreakendex=input.LastIndexOfAnybreakableCharacters,nextForcedLineBreak,maxLineLength+1; //如果没有可断开点,也就是说一个单词比行长,则强制将其断开。 如果nextbreakendex==0 { nextBreakIndex=nextForcedLineBreak; } 返回新StringSegmentinput、lastBreakIndex、nextBreakIndex-lastBreakIndex; lastBreakIndex=nextBreakIndex; } }
将\n添加到每行或System.Environment.NewLine的末尾您将要实现的目标有点不清楚。提供您的努力,即使编写了i伪代码。可能与Well的重复,那么我无法提供更多帮助,因为这将解决您的问题,但事实并非如此。因此,我应该假设您的代码中存在一些错误,因此如果您将代码包括在内,我们将更容易帮助您: