【问题标题】:String Index OutOfBOunds Exception字符串索引超出范围异常
【发布时间】:2014-07-23 02:21:14
【问题描述】:
public static void main(String [] args) throws IOException{
    BufferedReader in = new BufferedReader(new FileReader(".../senses/command_list"));
    String line = null;

    while((line = in.readLine()) != null){
        if(line.isEmpty()){
            continue;
        }
        line = line.trim();
        line = line.substring(2 + line.indexOf(">") , line.indexOf("))"));
        System.out.println(line);

    }

以下是文件的摘录

en_actions_.add(new ClusterEntry<String>("photography",-1, 2, 620554,"photography",null));
en_actions_.add(new ClusterEntry<String>("diagnostic procedure",-1, 1, 177127,"diagnostic procedure",null));
en_actions_.add(new ClusterEntry<String>("emergency procedure",-1, 1, 177783,"emergency procedure",null));
en_actions_.add(new ClusterEntry<String>("medical procedure",-1, 1, 1024392,"medical procedure",null));
en_actions_.add(new ClusterEntry<String>("process",-1, 5, 5470189,"process",null));

当我运行这个程序时,我遇到了一个字符串越界异常,并出现以下错误消息

线程“main”java.lang.StringIndexOutOfBoundsException 中的异常:字符串索引超出范围:-2
它指向带有 indexOf 运算符的行。

请让我知道我做错了什么。顺便说一句,该程序的目的是将每个字段存储在结构/类数组中。这只是程序的第一部分。

【问题讨论】:

  • 确定问题出在您的子字符串调用上。当您超过字符串的最大长度时会发生此错误。检查该部分(2+ line.indexOf(">"))是否不大于字符串的总长度
  • 尝试用 try...catch 块包围循环体,将违规行打印到标准错误。
  • 打印大部分行。异常会在中间某处弹出。
  • 可能与您的问题无关,但为什么不通过正则表达式提取文本?它保存了索引计算...
  • @Kent 我不熟悉正则表达式的工作。我真的应该学习。

标签: java string exception indexing


【解决方案1】:

好吧,我不知道你的文件有什么样的字符串(行),但你可能会得到一个长度为 1 的字符串,在这种情况下,下面的行会产生异常。

line = line.substring(2 + line.indexOf(">") , line.indexOf(")"));

此外,如果您的 String(line) 没有 ')',那么在这种情况下 line.indexOf(")") 将给出 -1,这是没有意义的。

另外,你自己试试下面的代码,同样的异常会重现。

String x = "a";
System.out.println(x.substring(2 + x.indexOf(">") , x.indexOf(")")));

在字符串 x 中,存储任何不包含 '>' 和 ')' 的字符串。

【讨论】:

  • 文件中的每一行都是我在问题中指定的格式。我很确定没有长度为 1 的字符串的行。
【解决方案2】:

文件中的某一行似乎没有&gt;) 字符。事实上,我在您的文件数据中根本看不到&gt;。运算符之一可能是多行的。将indexOf 提取到单独的变量中并检查这些符号是否存在。

int index1 = line.indexOf(">");
if (index1 < 0) {
 //skip this line
 continue;
}

此外,您可能希望交换 trimisEmpty 检查,以便过滤掉仅包含空格的行。

【讨论】:

  • > 字符在 中。我会尝试交换它。
  • 交换 trim 和 isEmpty 命令有效,但我不知道为什么。你能告诉我怎么做吗?谢谢!
  • @user3645570 想象一下,您在文件末尾有一行包含一堆空格,或者该行包含不可打印的字符。如果您使用isEmpty 测试该行,它将不起作用,因为字符串在技术上不是空的。如果您首先执行trim,这些字符将被删除,isEmpty 将执行它应该做的事情。
【解决方案3】:

您的异常原因比较清楚。回到您的要求,我认为这是典型的正则表达式用例。因为

  • 它使您免于计算 indexOf()。
  • 它保存了错误处理部分,例如index=-1 案例
  • 取决于你使用的jdk版本,如果

.

String s = "en_actions_.add(new ClusterEntry<String>(\"photography\",-1, 2, 620554,\"photography \",null));";
        Pattern p = Pattern.compile("(?<=>\\()[^)]*");
        Matcher m = p.matcher(s);
        if (m.find()) {
            System.out.println(m.group());
        }

上面的代码有一个look-behind regex,可以在&gt;()之间获取文本,如果你喜欢你可以添加&lt;string&gt;(作为look-behind模式。

如果它有点离题,我会删除答案。

【讨论】:

    【解决方案4】:

    可能会发生 2 件事:

    1. line.indexOf(")") 如果 String(line) 不包含 ')' 将返回 -1

    2. line.indexOf(")") ") 如果 ')' 出现在 String(line) 中的 '>' 之前

    如果 beginIndex 大于 endIndex,则 substring(begin_index,end_index) 函数将抛出 IndexOutOfBoundsException

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多