【问题标题】:Java - Counting words, lines, and characters from a fileJava - 计算文件中的单词、行和字符
【发布时间】:2019-03-14 03:51:08
【问题描述】:

我正在尝试从文件中读取单词。我需要计算文本文件中的单词、行和字符。字数应仅包括单词(仅包含字母,不包含标点符号、空格或非字母字符)。字符数应仅包括这些单词中的字符。

这是我目前所拥有的。我不确定如何计算字符数。每次我运行程序时,只要我输入文件名,它就会跳转到 catch 机制(文件路径应该没有问题,因为我之前尝试过使用它)。我尝试在没有 try/catch 的情况下创建程序以查看错误是什么,但没有它就无法工作。

为什么输入文件名会跳转到catch函数?如何修复此程序以正确计算文本文件中的字数、行数和字符数?

【问题讨论】:

  • 你对一个词的定义是什么?
  • 有什么异常?
  • 更新为(仅包含字母,不含标点、空格或非字母字符)
  • 这是我遇到的问题之一,它直接跳转到异常,除非存在异常,否则我无法运行程序
  • 您确定用户输入了正确的文件名吗?

标签: java java.util.scanner stringtokenizer


【解决方案1】:

如果我给出正确的文件名,我的代码不会有任何异常。至于读取字符数,你应该稍微修改一下逻辑。您应该创建一个 StringTokenizer st = new StringTokenizer(tempo, "[ .,:;()?!]+"); 的新实例,并遍历所有标记并对每个标记的长度求和,而不是直接连接字数。这应该给你字符数。像下面这样的

while (fileScan.hasNextLine()) {
            lineC++;
            tempo = fileScan.nextLine();
            StringTokenizer st = new StringTokenizer(tempo, "[ .,:;()?!]+");
            wordC += st.countTokens();
            while(st.hasMoreTokens()) {
                String stt = st.nextToken();
                System.out.println(stt); // Displaying string to confirm that like is splitted as I expect it to be
                charC += stt.length();
            }
            System.out.println("Lines: " + lineC + "\nWords: " + wordC+" \nChars: "+charC);
        }

注意:使用StringTokenizer 转义字符将不起作用。即你会期望\\s 应该用任何空白字符分隔,但它会改为基于文字字符s 分隔。如果你想转义一个字符,我建议你使用java.util.Patternjava.util.Matcher并使用它matcher.find()来识别单词和字符

【讨论】:

    【解决方案2】:

    我尝试了您的代码,但在这里没有收到任何异常。但是,我怀疑当您输入文件名时,您可能忘记了文件的扩展名。

    【讨论】:

      【解决方案3】:

      您可能在输入时忘记了文件扩展名,但有一种更简单的方法可以做到这一点。您还提到您不知道如何计算字符。你可以试试这样:

      import java.util.Scanner;
      import java.util.StringTokenizer;
      import java.io.*;
      import java.util.stream.*;
      
      public class WordCount
      {
          public static void main(String[] args)
          {
              Scanner userInput = new Scanner(System.in);
      
             try {
                  // Input file
                  System.out.println("Please enter the name of the file.");
                  String content = Files.readString(Path.of("C:/Users/garre/OneDrive/Desktop/" + userInput.next()));
                  System.out.printf("Lines: %d\nWords: %d\nCharacters: %d",content.split("\n").length,Stream.of(content.split("[^A-Za-z]")).filter(x -> !x.isEmpty()).count(),content.length());
                  }
      
      
              catch (IOException ex1) {
                  System.out.println("Error.");
                  System.exit(0);
              }
          }
      }
      

      浏览代码

      import java.util.stream.*;
      

      请注意,我们使用流包,用于在查找单词时过滤掉空字符串。现在让我们向前跳过一点。

      String content = Files.readString(Path.of("C:/Users/garre/OneDrive/Desktop/" + userInput.next()));
      

      以上部分获取文件中的所有文本并将其存储为字符串。

      System.out.printf("Lines: %d\nWords: %d\nCharacters: %d",content.split("\n").length,Stream.of(content.split("[^A-Za-z]")).filter(x -> !x.isEmpty()).count(),content.length());
      

      好的,这是一条很长的线。让我们分解一下。

      "Lines: %d\nWords: %d\nCharacters: %d" 是一个格式字符串,其中每个%d 都替换为printf 函数中的相应参数。第一个%d 将替换为content.split("\n").length,即行数。我们通过拆分字符串得到行数。

      第二个%dStream.of(content.split("[^A-Za-z]")).filter(x -> !x.isEmpty()).count() 替换。 Stream.of 从一个数组创建一个流,并且该数组是一个字符串数组,在您拆分任何非字母(您说单词是任何非字母)之后。接下来,我们过滤掉所有的空值,因为String.split 保留了空值。 .count() 是不言自明的,它采用过滤后剩余的字数。

      第三个也是最后一个%d 是最简单的。它被字符串的长度替换。 content.length() 应该是不言自明的。

      我保留了您的catch 块完好无损,但我觉得System.exit(0) 有点多余。

      【讨论】:

        猜你喜欢
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-02
        • 2013-02-20
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        相关资源
        最近更新 更多