本文详解如何将字符串按每行最多 N 个字符自动换行,且确保断点位于最近的空格位置,避免单词被截断;重点解析 indexOf(" ", fromIndex) 的正确用法及常见索引越界错误的规避方法。
本文详解如何将字符串按每行最多 n 个字符自动换行,且确保断点位于最近的空格位置,避免单词被截断;重点解析 `indexof(" ", fromindex)` 的正确用法及常见索引越界错误的规避方法。
在文本处理中,常需将长字符串“智能换行”——即限制每行最大宽度(如 20 字符),但不能在单词中间切断,而应退回到前一个空格处断行。初学者易犯的典型错误是:硬编码 endPos = 20 后直接调用 substring(startPos, endPos),忽略字符串实际长度和空格位置,导致 StringIndexOutOfBoundsException。
✅ 正确思路:动态查找最近空格
关键在于:不强制在第 20 位截断,而是从第 20 位开始向后搜索第一个空格;若未找到,则向前搜索最后一个空格;若仍无空格(如超长单词),则强制在 20 位截断。
Java 提供了高效工具:String.indexOf(String str, int fromIndex) —— 从指定下标起向后查找子串首次出现位置。例如:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
String text = "Hello there, I am doing some coding, I need some help";
int pos = text.indexOf(" ", 20); // 从索引20开始找空格
System.out.println(pos); // 输出 23("am"后的空格)✅ 完整可运行示例(支持边界处理)
import java.util.Scanner;
public class SmartLineBreaker {
private static final int MAX_LINE_WIDTH = 20;
public static void main(String[] args) {
System.out.print("Please input a string: ");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine().trim();
int startPos = 0;
while (startPos < input.length()) {
int endPos = startPos + MAX_LINE_WIDTH;
// 情况1:剩余字符不足MAX_LINE_WIDTH → 直接取到末尾
if (endPos >= input.length()) {
System.out.println(input.substring(startPos));
break;
}
// 情况2:从startPos+MAX_LINE_WIDTH开始向后找空格
int spacePos = input.indexOf(" ", endPos);
if (spacePos != -1) {
// 找到后续空格 → 在该空格处断行(保留空格前内容)
System.out.println(input.substring(startPos, spacePos));
startPos = spacePos + 1; // ✅ 关键:startPos跳到空格后一位,跳过该空格
} else {
// 情况3:向后无空格 → 向前找最后一个空格
spacePos = input.lastIndexOf(" ", endPos);
if (spacePos != -1) {
System.out.println(input.substring(startPos, spacePos));
startPos = spacePos + 1;
} else {
// 情况4:当前段无任何空格(如超长单词)→ 强制截断
System.out.println(input.substring(startPos, endPos));
startPos = endPos;
}
}
}
scanner.close();
}
}⚠️ 注意事项与常见陷阱
- startPos = endPos + 1 的含义:endPos 是空格的索引,substring(startPos, endPos) 取的是 [startPos, endPos) 区间(左闭右开),因此 startPos = endPos + 1 是为了跳过空格本身,从下一个字符开始新一行。若误写为 startPos = endPos,会导致空格被重复输出或索引错位。
- 空指针与越界防护:务必检查 indexOf() 返回 -1(未找到),否则直接用于 substring() 会抛异常。
- 首尾空格处理:建议对输入 trim(),避免开头/结尾多余空格干扰断行逻辑。
- 性能提示:对超长文本,可考虑使用 StringBuilder 缓存结果再统一输出,减少 I/O 开销。
通过此方案,输入 "Hello there, I am doing some coding, I need some help" 将精准输出:
立即学习“Java免费学习笔记(深入)”;
Hello there, I am doing some coding, I need some help
每一行 ≤20 字符,且严格在单词边界断开——这才是健壮、用户友好的文本换行实现。

















