【问题标题】:Going through a txt file and finding sum of integers with exception遍历一个 txt 文件并找到异常的整数和
【发布时间】:2018-02-04 23:16:52
【问题描述】:

我有一个程序,它假设询问用户什么 txt 文件,浏览 txt 文件并找到所有可解析的整数并将它们平均。我在下面有以下代码,但它给了我一堆错误。所有这些错误的原因是什么?

txt文件为: 5 15 312 16 八七 44 八万五千六十二 13 98 93

import java.util.Scanner;


public class Ch12Pt2 {
public static void main(String[] args) throws NumberFormatException {
Scanner input = new Scanner(System.in);
System.out.print("Enter filename: ");
String filename = input.nextLine();
Scanner file = new Scanner(filename);

if(file.nextLine().equals(""))
{
    System.err.println("Could not find file:" + filename);
    System.exit(1);
}

do {
      try {
            int total = 0;
            int count = 0;
        int num = file.nextInt();
        total = num + total;

        //Display the results
        System.out.println("The number of parsable numbers: " + count);
        System.out.println("Average values: " + (total / count));




      } 
      catch (NumberFormatException ex) {
        System.out.println("Cannot parse " + num + " as an integer.");
        file.nextInt();
      }

    } while (file.hasNextInt());

// Close the files
input.close();
file.close();
   }
}

Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Ch12Pt2.main(Ch12Pt2.java:21)

【问题讨论】:

  • eight 不是int,因此file.nextInt() 将失败
  • @MadProgrammer 我认为 NumberFormatException 会控制它。
  • java.util.NoSuchElementException 不继承自 NumberFormatException 或任何共同祖先,所以我不会抓住它
  • 另外,Scanner file = new Scanner(filename); 不正确,这是将String filename 传递给要处理的Scanner,相反,您可能是指Scanner file = new Scanner(new File(filename));,它实际上会读取指定的文件

标签: java exception


【解决方案1】:

如果您查看 constructor you used 的 JavaDoc,您会发现它“构造一个新的扫描器,生成从指定字符串扫描的值”。你想要的是Scanner#Scanner(File source),“......一个新的扫描仪,它产生从指定文件扫描的值”。

不要使用do-while,如果你的文件没有任何整数,它会通过一个空指针。改用while。此外,不要在循环内初始化 任何 变量。这将导致它们在每次迭代时重新初始化。

file.nextInt(); 在你的 catch 块中有什么意义?它会导致程序跳过一个额外的整数。去掉它。另外,不要调用input.close();,你也不想关闭System.in

    @SuppressWarnings("resource")
    Scanner input = new Scanner(System.in);
    System.out.println("Enter filename: ");
    File file = new File(input.nextLine());

    /*
     * Check file existence before constructing your scanner. This will prevent a
     * FileNotFoundException. Notice, I used File#exists and the NOT operator '!'
     */
    if (!file.exists()) {
        System.err.println("Could not find file: " + file.getName());
        System.exit(0);
    }

    Scanner scanner = new Scanner(file);

    // Initialize variables outside of loop.
    int num = 0;
    int total = 0;
    int count = 1;
    // No do-while
    while (scanner.hasNextInt()) {
        try {
            num = scanner.nextInt();
            total += num;

            // Display the results
            System.out.println("The number of parsable numbers: " + count);
            System.out.println("Average values: " + (total / count));

            // count is pointless unless you increase it after every number.
            count++;
        } catch (NumberFormatException ex) {
            System.out.println("Cannot parse " + num + " as an integer.");
        }

    }

    // Close the files
    scanner.close();

最后,正如疯狂程序员所指出的,“八七”和“八万五千六十二”不是数字,因此Scanner#nextInt 不会包含它们。一种解决方法是使用Scanner#nextLine 并进行相应的解析。像这样的东西:How to convert words to a number?

【讨论】:

    【解决方案2】:

    您的代码几乎都是错误的。我已经对其进行了重新设计,现在它可以工作了。

    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.util.Scanner;
    
    
    public class Ch12Pt2 {
        public static void main(String[] args) throws NumberFormatException, FileNotFoundException {
            Scanner input = new Scanner(System.in);
            System.out.print("Enter filename: ");
            String filename = input.nextLine();
            Scanner file = new Scanner(new FileReader(filename));
            int num =0;
            int count =0;
            int total =0;
    
            if(file.nextLine().equals(""))
            {
                System.err.println("Could not find file:" + filename);
                System.exit(1);
            }
    
            while (file.hasNextInt()){
                try {
                        num = file.nextInt();
                        total = num + total;
                       count++;
    
    
                }
                catch (NumberFormatException ex) {
                    System.out.println("Cannot parse " + num + " as an integer.");
                }
    
            }
    
    // Close the files
            input.close();
            file.close();
            System.out.println("The number of parsable numbers: " + count);
            System.out.println("Average values: " + (total / count));
        }
    
    }
    

    【讨论】:

    • 我可以看出你是新来的。这里让我给你一些建议。 永远不要把代码交给别人。而是解释他们犯了什么错误,为什么是错误(如果可以的话),以及你是如何修复它的。
    • 知道了。感谢您的建议。好吧,他的代码中的所有内容都是错误的,因此很难帮助他。下次还记得哦?
    【解决方案3】:

    扫描仪文件 = 新扫描仪(文件名);

    线程“主”java.util.NoSuchElementException 中的异常

    如果您使用扫描仪从文本文件中读取数据,则需要指定文件,而不是字符串,这就是您收到上述错误的原因。

    用途:

    Scanner scanner = new Scanner(new FileReader("foo.txt"));
    

    然后像这样递归遍历文本文件:

    while(scanner.hasNext())
    

    您的代码:

    while (file.hasNextInt());

    将不起作用,因为 hasNextInt() 方法会在遇到除整数以外的任何内容时停止处理文本文件。

    System.out.println("无法将 " + num + " 解析为整数。");

    变量 num 在与处理异常的主体不同的范围内定义。由于未在 NumberFormatException 正文中定义 num,因此将引发额外的错误。

    txt文件为:5 15 312 16 八七 44 八万五六十二 13 98 93

    如果文本文件中的项目在同一行,最好使用split方法获取所有元素,然后检测它们是否为数字。

    String line = sc.nextLine();
    String elements = line.split(" ");
    for (String e : elements) {
     // add if int, or continue iteration
    }
    

    否则,请尝试以下方式:

    int sum = 0;
    int numElements = 0;
    Scanner scanner = new Scanner(new FileReader("path-to-file"));
    while (scanner.hasNext()) {
        try {
          int temp = Integer.parseInt(sc.nextLine());
          sum += temp;
          numElements += 1;
        }catch(NumberFormatException e) {
          continue;
        } 
    }
    
    System.out.println("Mean: "+ (sum/numElements));
    

    【讨论】:

    • "...hasNextInt() 方法将在遇到除整数以外的任何内容时停止处理文本文件。"实际上并非如此。如果输入中有 any 个整数,它将返回 true。
    • @CardinalSystem 您应该正确引用。 “Lord Why”在该句子中包含来自 OPs 代码的 while,他是对的,如果下一个令牌不是 int,它将停止处理/循环。但是您的句子“如果输入中还有任何整数,它将返回true。”是错的。该方法检查下一个标记,而不是输入流中留下的任何标记。
    • 其实不会,只有输入流中的下一组字符可以读取为int类型时才会返回true。根据官方 Javadoc,“如果此扫描仪输入中的下一个标记可以使用 nextInt() 方法解释为默认基数中的 int 值,则返回 true。”
    猜你喜欢
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    相关资源
    最近更新 更多