
本文介绍如何将字符串按最大宽度(如20字符)自动断行,且确保断点位于最近的空格处,避免单词被截断,适用于控制台文本格式化、日志输出或简单排版场景。
本文介绍如何将字符串按最大宽度(如20字符)自动断行,且确保断点位于最近的空格处,避免单词被截断,适用于控制台文本格式化、日志输出或简单排版场景。
在文本处理中,简单按固定长度切分字符串(如每20个字符一换行)容易导致单词被强行截断(如 "doing" 变成 "do"),影响可读性。理想方案是:优先在不超过指定长度的前提下,寻找最靠右的空格作为断点;若该范围内无空格,则退而求其次在指定位置硬断(即允许单个超长单词存在)。这是一种兼顾语义完整性与布局约束的“智能换行”策略。
实现思路如下:
- 从起始位置 start 开始,计算理论结束位置 end = start + maxLength;
- 若 end 超出字符串总长,直接输出剩余子串并结束;
- 否则,从 end 位置逆向搜索(含 end 本身),查找第一个空格 ' ';
- 若找到空格索引 spaceIdx,则以 spaceIdx 为界切分:[start, spaceIdx) 为当前行,spaceIdx + 1 为下一行起点;
- 若未找到空格(即该段无空格),则强制在 end 处断开([start, end)),并从 end 继续处理。
以下是完整、健壮的 Java 实现:
public static void wrapText(String input, int maxWidth) {
if (input == null || input.isEmpty() || maxWidth <= 0) {
System.out.println(input);
return;
}
int start = 0;
while (start < input.length()) {
int end = Math.min(start + maxWidth, input.length());
// 若已到末尾,直接输出并退出
if (end == input.length()) {
System.out.println(input.substring(start));
break;
}
// 逆向查找空格(从 end-1 开始,避免越界)
int spaceIdx = -1;
for (int i = end - 1; i >= start; i--) {
if (input.charAt(i) == ' ') {
spaceIdx = i;
break;
}
}
if (spaceIdx != -1) {
// 找到空格:输出 [start, spaceIdx),下一轮从 spaceIdx+1 开始
System.out.println(input.substring(start, spaceIdx));
start = spaceIdx + 1;
} else {
// 未找到空格:强制在 end 处断行(保留完整单词)
System.out.println(input.substring(start, end));
start = end;
}
}
}使用示例:
public static void main(String[] args) {
System.out.print("Please input a sentence: ");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
wrapText(input, 20); // 按最大20字符宽度智能换行
}输入:
hello there, I am doing some coding!
输出:
hello there, I am doing some coding!
✅ 关键注意事项:
- 逆向搜索范围必须限定在 [start, end-1](而非 [start, end]),因为 charAt(end) 会越界(字符串索引最大为 length()-1);
- 需显式处理 input.length() == 0 或 maxWidth
- 当某段内无空格时(如超长URL或单词),强制断行是合理兜底策略——若业务要求绝不硬断,可改为抛出异常或返回错误提示;
- 本方案时间复杂度为 O(n),空间复杂度 O(1)(仅创建必要子串),适合常规文本处理。
该方法简洁、可复用,既满足初学者理解逻辑的需求,也具备生产环境所需的鲁棒性。掌握此模式后,还可轻松扩展支持制表符、换行符等其他空白字符,或集成进 StringBuilder 流式处理流程中。

















