【问题标题】:java: 'string index out of range: -1' exception using indexOf()java: '字符串索引超出范围: -1' 使用 indexOf() 异常
【发布时间】:2012-06-07 05:55:36
【问题描述】:

奇怪的问题。我运行这个(非常基本的)程序在文件中查找用户名和密码,程序应该将输入的密码与保存的密码进行比较。然而,每次我都会得到一个奇怪的String index out of range: -1 异常。我以前遇到过类似的问题,但是这次indexOf('.') 调用返回-1;它不喜欢。如果 indexOf() 导致错误,为什么会返回 -1?这是来源:

public String loginToClient() throws FileNotFoundException, IOException {
        //decryptUsers();
        int tries;
        tries = 5;
        while (tries > 0) {
            System.out.println("LOGIN");
            String usnm = c.readLine("Username: ");
            char [] passwd = c.readPassword("Password: ");
            users = new FileInputStream("users.fra");
            DataInputStream dis = new DataInputStream(users);
            BufferedReader br = new BufferedReader(new InputStreamReader(dis));
            String logindat = br.readLine();
            System.out.println(logindat);
            if (logindat.contains(usnm) == null) {
                System.err.println("Username not recognised, please try another or create user.");
                usnm = "INV";
                return usnm;
            }
            else {
                int startUsnm = logindat.indexOf(usnm);
                System.out.println("startUsnm: " + startUsnm);
                String logdat = logindat.substring(startUsnm, logindat.indexOf("."));
                System.out.println("logdat: " + logdat);
                int endUsnm = logdat.indexOf(':'); 
                System.out.println("endUsnm: " + endUsnm);
                int usnmend = endUsnm - 1;
                System.out.println("usnmend: " + usnmend);
                int startPass = endUsnm + 1;
                System.out.println("startPass: " + startPass);
                int endPass = logdat.indexOf('.');
                System.out.println("endPass: " + endPass);
                String Usnm = logdat.substring(0, usnmend);
                System.out.println("Usnm: " + Usnm);
                int passend = endPass - 1;
                System.out.println("passend: " + passend);
                String Pass = logdat.substring(startPass, passend);
                System.out.println("Pass: " + Pass);
                char [] Passwd = Pass.toCharArray();
                if (usnm.equals(Usnm)) {
                    if (Arrays.equals(passwd,Passwd)) {
                        System.out.println ("Logged in. Welcome, " + usnm + ".");
                        String data = "LOGIN: " + usnm;
                        printLog(data);
                        //encryptUsers();
                        return usnm;
                    }
                    else {
                        System.out.println ("Incorrect password, please try again.");
                        String data = "PASWFAIL: " + usnm;
                        printLog(data);
                        tries -= 1;
                    }
                }
                else {
                    System.out.println ("Username not recognised.");
                    printLog("USNAMFAIL");
                    usnm = "INV";
                    return usnm;
                    //encrytUsers();
                }
            }
        }
        //encryptUsers();
        System.exit(2);
        return usnm;
    }

这里有一些输入/输出:

Startup initiated.
Logfile exists.
Users file exists.
New user? n
ELSE
LOGIN
Username: rik
Password: 
rik:55.
startUsnm: 0
endUsnm: 3
startPass: 4
endPass: -1
Usnm: rik
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -5
    at java.lang.String.substring(String.java:1949)
    at client0_0_2.loginToClient(client0_0_2.java:103)
    at client0_0_2.general(client0_0_2.java:209)
    at client0_0_2.<init>(client0_0_2.java:221)
    at client0_0_2.main(client0_0_2.java:228)

编辑:找到解决方案!

由于某种原因,indexOf() 不想找到一个 '.'- 当替换为连字符 ('-') 时,它看起来运行完美!

【问题讨论】:

  • 记住:“第一个”索引是0。“-1”表示“未找到”? else 您希望“indexOf()”如何返回“未找到”的值?抛出异常可能是一个合理的选择。但是您不想只检查“-1”吗?您可以通过查看 "String" 的 Javadocs 轻松找到它
  • 遇到了同样的问题,点肯定存在于字符串中,但 indexOf('.') 以某种方式返回 -1。

标签: java string indexof indexoutofboundsexception


【解决方案1】:

我认为错误在这一行:

String Pass = logdat.substring(startPass, passend);

出于某种原因(您必须确定原因),您通过在字符串中搜索 . 来计算 passend。如果. 不存在,indexOf 返回 -1 作为哨兵。不过,这不是导致异常的行。我认为是上面那行,因为如果你在passend 为-1 时尝试计算以passend 结尾的子字符串,你会得到上述错误。

尝试确定为什么您的字符串中不包含.

希望这会有所帮助!

【讨论】:

  • -我第二次运行这个(有修改),它似乎从末尾删除了一个字符-它不是以前...- 忽略这个
  • 哦,还有 - 永远不要以纯文本形式存储密码!这是一场即将发生的安全噩梦。
  • 谢谢,我知道 xD 我刚刚弄湿了,加密让我有点困惑,所以我在对简单的事情进行排序时坚持使用纯文本。我正在准备加密,正如您通过注释掉的方法调用 xP 所看到的那样,谢谢您,绝对是个好建议! :D
  • 您不需要加密。您只需要应用一个哈希函数(我建议使用 SHA2),保存密码的哈希值,并在使用相同函数进行哈希处理后与用户输入进行比较。
  • 非常感谢,sergi :D 我明天重新开始工作时会这样做。
【解决方案2】:

indexOf()返回-1时,表示在String中找不到该值。因此,在这种情况下,您正在为字符串中不存在的 '.' 搜索字符串。

我建议您始终在通话后检查indexOf() 的值,并正确处理-1。在许多情况下,将其设置为 0string.length() 可能就足够了,这取决于您稍后在代码中将如何使用它。

无论如何,如果您希望 '.' 存在但不存在,则需要通过代码进行调试以找出值是什么,以及缺少 '.' 的位置。

【讨论】:

  • 似乎点肯定存在,并且当搜索到的字符串被打印时,它(现在)包含它。它似乎仍然返回 -1:我将使用 string.length() :D 很好的建议,谢谢。
  • 我能问一下,你为什么要这样做...int passend = endPass - 1;?当您调用indexOf(".") 时,它将立即返回位置的索引之前 .。我假设您正在执行endPass - 1 以尝试从substring() 中删除点,在这种情况下不需要这样做,这可能是您的错误所在。
  • 我相信这可能是问题的原因之一——即使删除了那条线,它也没有检测到点;我把它改成了连字符,它起作用了。不过谢谢,这也会导致错误!
【解决方案3】:

如果找不到指定的字符串,indexOf() 返回-1

问题出在一行:

String Pass = logdat.substring(startPass, passend);

因为负索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 2012-06-04
    • 1970-01-01
    相关资源
    最近更新 更多