【问题标题】:Is there any way to automatically break lines in a cmd window?有什么方法可以在 cmd 窗口中自动换行吗?
【发布时间】:2015-08-15 12:33:27
【问题描述】:

我和我的朋友编写了一个简单(但很长)的基于文本的游戏,该游戏在 Windows 命令提示符下运行。问题是,cmd 窗口没有像 Microsoft word 中那样包含任何类型的自动换行符,因此使游戏无法玩。如果我不是很清楚,这是一个关于现在游戏如何玩的例子:

You wake up in a dark room. Wherev
er you look, you can't see anythin
g. You try to move, but you can't;
your hands are tied down by the lo
oks of it.

有什么简单的方法可以解决这个问题吗?游戏长达 2000 多行,因此我们可能永远无法一个接一个地修正句子。

编辑:为了清楚起见,我想要实现以下目标:

You wake up in a dark room.
Wherever you look, you can't see
anything. You try to move, but
you can't; your hands are tied
down by the looks of it.

【问题讨论】:

  • 我不确定你想做什么,但如果所有游戏都写入 System.out,那么你可以使用 System.setOut(...) 将其设置为你自己的PrintStream 将其重定向到 System.out,仅添加了换行符。
  • 如何做到这一点?互联网上有某种教程吗?我是 Java 的初学者。
  • 这取决于你的换行标准是什么......
  • 基本上cmd窗口每行字符限制为80个,然后在下一行继续打印出文本。我的标准如下:在每 80 个字符中,它会查找最后一个空格并打印出一个新行。这有可能实现吗?
  • 在我看来似乎很难实现,因为您没有命令提示符窗口的属性。 (字体、文本尺寸、窗口尺寸)这听起来比实际从一些教程中获取文本区域的示例代码并将系统重定向到那里要麻烦得多。只需一点点工作,您甚至可以根据需要使其看起来像命令行提示符。

标签: java


【解决方案1】:

通常,宽度为 72 的行用于使文本易于阅读,因此我建议坚持这一点,不要试图计算文本终端的宽度。要实现正确的自动换行,最好的选择是依赖 Apache WordUtils,它包含 wrap 方法。或者(如果您不想为此下载另一个 JAR),只需将其实现复制到您的项目中:

/*
 * Copyright 2002-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
public static String wrap(String str, int wrapLength, String newLineStr, boolean wrapLongWords) {
    if (str == null) {
        return null;
    }
    if (newLineStr == null) {
        newLineStr = SystemUtils.LINE_SEPARATOR;
    }
    if (wrapLength < 1) {
        wrapLength = 1;
    }
    int inputLineLength = str.length();
    int offset = 0;
    StringBuilder wrappedLine = new StringBuilder(inputLineLength + 32);

    while ((inputLineLength - offset) > wrapLength) {
        if (str.charAt(offset) == ' ') {
            offset++;
            continue;
        }
        int spaceToWrapAt = str.lastIndexOf(' ', wrapLength + offset);

        if (spaceToWrapAt >= offset) {
            // normal case
            wrappedLine.append(str.substring(offset, spaceToWrapAt));
            wrappedLine.append(newLineStr);
            offset = spaceToWrapAt + 1;

        } else {
            // really long word or URL
            if (wrapLongWords) {
                // wrap really long word one line at a time
                wrappedLine.append(str.substring(offset, wrapLength + offset));
                wrappedLine.append(newLineStr);
                offset += wrapLength;
            } else {
                // do not wrap really long word, just extend beyond limit
                spaceToWrapAt = str.indexOf(' ', wrapLength + offset);
                if (spaceToWrapAt >= 0) {
                    wrappedLine.append(str.substring(offset, spaceToWrapAt));
                    wrappedLine.append(newLineStr);
                    offset = spaceToWrapAt + 1;
                } else {
                    wrappedLine.append(str.substring(offset));
                    offset = inputLineLength;
                }
            }
        }
    }

    // Whatever is left in line is short enough to just pass through
    wrappedLine.append(str.substring(offset));

    return wrappedLine.toString();
}

【讨论】:

    【解决方案2】:

    一个非常简单的例子。在您的情况下,您可能需要存储您的输入,直到出现换行符等,但我希望您了解基本概念......

    public class RedirectPrintStream extends PrintStream {
    
        private static String NEW_LINE = String.format("%n"); // This creates the system-specific line break (depends on Windows/Linux/etc)
    
        public RedirectPrintStream(OutputStream out) {
            super(out); 
        }
    
        @Override
        public void print(String obj) {
            super.print(obj);  // or check here if the obj.length > 80 and add another line break, etc.
            super.print(NEW_LINE);
    
        }
    
        public static void main(String[] args) {
    
            PrintStream old = System.out;
            System.setOut( new RedirectPrintStream(old));
    
            System.out.print("Hello");
            System.out.print("World"); // will be printed in a new line instead of the same
    
        }
    }
    

    至于包装本身,我将支持已经提到的来自 Apache Commons lang 的 WordUtils。应该很简单。

    【讨论】:

    • 据我了解,OP 最大的问题是,在哪里打破界限,而不是如何。这可能会有所帮助,但找出每行有多少个字符对于这通常是至关重要的。这不是完整的答案。
    • 好的,为此添加了一些内容。我个人也会为此使用 Apache Commons Lang。无需从头开始编写所有内容。
    【解决方案3】:

    这不是真正的 java 问题,正如标签所暗示的那样,但如果您使用 System.out 作为输出, 你可以:

    1. 根据需要更改 Windows cmd 宽度
    2. 根据this链接,动态获取你的cmd宽度。 然后,创建一个类的对象,这将是您的输出处理程序。获取宽度并将其保存为字段。然后,每当您需要输出时,调用它的方法,该方法会自动在您的字符串中放置换行符,然后调用重定向到 system.out。

    【讨论】:

    • 链接说明 jline2 可以使用,但实际上它有一个名为 jansi 的传递依赖项,并使用其内部 API(在 Github 上的当前版本中已删除)。 Jansi 要求系统上存在本机 DLL。
    猜你喜欢
    • 2010-09-06
    • 2014-09-08
    • 1970-01-01
    • 2011-01-30
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    相关资源
    最近更新 更多