【问题标题】:read a String in a text file读取文本文件中的字符串
【发布时间】:2016-07-01 01:40:00
【问题描述】:

假设我的文本文件中有此文本:

VOTED/1/hannah/18
NOT VOTING/2/janice/20

我有这个代码:

File Orig_outFile = new File("C:\\voters.txt");
BufferedReader infile = new BufferedReader(new FileReader(Orig_outFile));

vNum=JOptionPane.showInputDialog("Enter voters number: ");
String line="";
String something="VOTED";
while(infile.readLine()!=null){
    line=infile.readLine();
    String [] info=line.split("/");

    if(info[1].matches(vNum)){
    while(info[0].matches(something)){
        JOptionPane.showMessageDialog(null, "Voter already voted or Voter not registered. Please try again");
        vNum=JOptionPane.showInputDialog("Enter voters number: ");
    }
    President();
    }
}
infile.close();

任务是用户需要输入一个投票人的号码,然后读取文本文件,然后如果发现文本文件中的info[0]包含VOTED会报错,需要输入又是选民的号码。我假设我的错误是我使用了两次 while 循环?

【问题讨论】:

  • 此代码会在发生异常时泄漏infile资源。

标签: java bufferedreader file-handling


【解决方案1】:

调用infile.readLine() 实际上是从文件中读取一行,将其返回并移至下一行。您调用它两次,一次在 while 循环条件中:

while(infile.readLine() != null)

再循环的第一行:

line = infile.readLine();

您应该只在 while 循环条件中调用它一次并将值分配给 line 变量,如下所示:

while((line = infile.readLine()) != null)

【讨论】:

  • 我以为我在下面的回答中提到了同样的事情?
【解决方案2】:

实际上,您正在通过执行infile.readLine() 读取while 中的一行,并通过再次执行infile.readLine() 将下一行附加到字符串line

您最终只能从文件中读取第二行。您应该按如下方式更改您的 while 循环:

while((line = infile.readLine()) != null)

并删除以下语句:

line = infile.readLine();

这里是修正后的代码sn-p:

File Orig_outFile = new File("C:\\voters.txt");
BufferedReader infile = new BufferedReader(new FileReader(Orig_outFile));

vNum = JOptionPane.showInputDialog("Enter voters number: ");
String line = null;
String something = "VOTED";
while((line = infile.readLine()) != null) {
    String [] info = line.split("/");

    /* Assuming You Are Entering Voter's Number & Not Voter's Name */
    if(info[1].equalsIgnoreCase(vNum)) {
        if(info[0].equalsIgnoreCase(something)) {
            JOptionPane.showMessageDialog(null, "Voter already voted or 
                                          Voter not registered. Please try again");
            /* Please Note That You Are Currently Iterating File */
            /* If You Do This Here, You'll End Up Checking Same Records */
            /* You'll Have To Replace Outer `if` with `while` */
            vNum = JOptionPane.showInputDialog("Enter voters number: ");
        } else {
            President();
            break;
        }
    }
}
infile.close();

这是一个更清晰的实现方法:

  1. 读取内存中的完整文件(最好是Map,带有键 -> 选民编号)。

  2. 从用户那里获取选民编号并检查它是否存在于地图中。

  3. 如果它在 Map 中不存在或值等于 VOTED,则重复 Step 2

这里是sn-p的代码:

File Orig_outFile = new File("C:\\voters.txt");
BufferedReader infile = new BufferedReader(new FileReader(Orig_outFile));
Map<String,String> map = new HashMap<>();
String something = "VOTED";

String line = null;
while((line = infile.readLine()) != null) {
    String [] info = line.split("/");
    map.add(info[1],info[0]);
}
infile.close();

while(true) {
    vNum = JOptionPane.showInputDialog("Enter Voter's Number: ");
    if(map.contains(info[1]) && !map.get(info[1]).equalsIgnoreCase(something)) {
        President();
        break;
    } else {
        JOptionPane.showMessageDialog(null, "Voter already voted or 
                                          Voter not registered. Please try again");
    }
}

【讨论】:

  • 哦,什么都没发生。它仍然是一样的,它甚至不会读取文本文件或类似的东西。它会跳过 if 和 while 条件,直接转到 President() 方法
  • @pep 我希望您输入类似18 的内容作为选民编号而不是选民姓名。在那种情况下不应该是info[2] 而不是info[1]
  • 哦,我刚刚注意到,我现在编辑了我的问题。实际上选民的号码在 info[1] 中,而 info[3] 或 18 是年龄 :) 是的,我会试试这个,如果它有效,我会告诉你 :)
  • @pep 您应该先读取内存中的文件,然后再从用户那里获取输入。检查更新的解决方案。
猜你喜欢
  • 1970-01-01
  • 2016-01-15
  • 2015-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 1970-01-01
  • 2014-07-28
相关资源
最近更新 更多