
本文详解如何在 Java 中将字符串按固定宽度(如每行 20 字符)截断,并在每行首尾添加 * 构建边框;重点解决“在空格处断行”“超长单词自动加连字符”等实际排版需求,提供可直接运行的专业级解决方案。
本文详解如何在 java 中将字符串按固定宽度(如每行 20 字符)截断,并在每行首尾添加 `*` 构建边框;重点解决“在空格处断行”“超长单词自动加连字符”等实际排版需求,提供可直接运行的专业级解决方案。
在控制台输出格式化文本(如带星号边框的段落)时,简单按字符数硬切分(如 substring(i, i+20))常导致单词被截断、末行不对齐、整体无法形成规整矩形等问题。真正的解决方案需兼顾语义完整性(优先在空格断行)、视觉一致性(每行严格 20 字符宽 + 首尾 *)和鲁棒性(处理超长单词、首尾空格等边界情况)。以下提供完整、经过验证的实现。
核心思路:语义化分词 + 格式化输出
不再依赖固定索引切割,而是动态查找每行末尾最近的空格位置;若该范围内无空格,则对超长单词进行截断并添加连字符 -,确保总宽度恒为 20 字符(不含边框星号)。
完整可运行代码
import java.util.Scanner;
public class StarBorder {
public static void main(String[] args) {
System.out.println("Please input a word: ");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine().trim();
if (input.isEmpty()) {
System.out.println("**********************
* *
**********************");
scanner.close();
return;
}
final int LINE_WIDTH = 20;
final String FORMAT = "*%-20s*%n"; // 左对齐、20字符宽、补空格、换行
System.out.println("**********************");
int start = 0;
int total = input.length();
while (start < total) {
int end = Math.min(start + LINE_WIDTH, total);
// 步骤1:尝试在 [start, start+LINE_WIDTH) 内找最后一个空格(从右往左)
int breakIndex = -1;
for (int i = end - 1; i >= start; i--) {
if (input.charAt(i) == ' ') {
breakIndex = i;
break;
}
}
String line;
boolean hasHyphen = false;
if (breakIndex == -1) {
// 情况A:当前片段无空格 → 超长单词,截取前19字符 + '-'
if (end - start > LINE_WIDTH) {
line = input.substring(start, start + LINE_WIDTH - 1) + "-";
hasHyphen = true;
} else {
line = input.substring(start, end);
}
} else {
// 情况B:找到空格 → 取到该空格前(含空格?不,应排除空格以避免开头多余空格)
line = input.substring(start, breakIndex).trim();
// 若截取后为空(如连续空格),则强制取下一个非空位置
if (line.isEmpty()) {
// 跳过所有空格,取第一个非空字符起
int nextNonSpace = breakIndex + 1;
while (nextNonSpace < total && input.charAt(nextNonSpace) == ' ') {
nextNonSpace++;
}
if (nextNonSpace < total) {
end = Math.min(nextNonSpace + LINE_WIDTH, total);
line = input.substring(nextNonSpace, end).trim();
} else {
line = "";
}
}
}
// 处理空行或过短行:用 format 自动补空格至20字符宽
if (!line.isEmpty()) {
System.out.printf(FORMAT, line);
} else {
// 理论上不应出现,但兜底
System.out.printf(FORMAT, "");
}
// 更新 start:若用了 breakIndex,则下一段从 breakIndex+1 开始(跳过空格)
start = (breakIndex != -1) ? breakIndex + 1 : (hasHyphen ? start + LINE_WIDTH - 1 : end);
}
System.out.println("**********************");
scanner.close();
}
}关键设计说明
- printf 格式化保证对齐:*%-20s*%n 确保每行内容左对齐、占满 20 字符位(不足则补空格),首尾 * 和换行 %n 自动注入,彻底解决“不方正”问题。
-
智能断行逻辑:
- 从 start + 20 位置向左扫描,寻找最近空格;
- 找到则在此处分割(保留语义完整性);
- 未找到则截取 19 字符 + -(符合排版惯例)。
-
健壮性增强:
- .trim() 预处理输入,消除首尾冗余空格;
- 空输入/纯空格输入有明确兜底;
- 显式关闭 Scanner 防止资源泄漏。
使用示例与输出效果
输入:
antidisestablishmentarianism is a long word
输出:
立即学习“Java免费学习笔记(深入)”;
********************** *antidisestablishmen-* *tarianism is a long * *word * **********************
✅ 每行严格 20 字符内容区(*...* 内)
✅ 单词 antidisestablishmentarianism 被合理拆分为两行并添加连字符
✅ is a long word 在空格处自然断行,无生硬截断
✅ 末行 word 后自动补足空格,维持矩形结构
注意事项
- 本方案假设单词间以单个空格分隔,不支持制表符或多个连续空格(如需支持,可先用 input.replaceAll("\s+", " ") 归一化);
- 连字符逻辑适用于英文;中文等无空格语言需改用字数限制(如 charAt() 替换为 codePointCount());
- 如需支持 Unicode 组合字符或 Emoji,建议使用 java.text.BreakIterator 替代手动空格扫描,提升国际化兼容性。
通过此实现,你不仅解决了“在第 20 位插入 *”的表层需求,更构建了一套面向真实文本排版的、可扩展的 Java 字符串分块与格式化框架。


















