Java - 计算文件中的字数、行数和字符数

Java - Counting words, lines, and characters from a file

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

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

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

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

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.*;

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

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) 有点多余。

我试过你的代码,但我没有收到任何异常。不过,我怀疑你在输入文件名的时候,可能忘记了文件的扩展名。

如果我提供正确的文件名,我不会对您的代码有任何例外。至于读取字符数,你应该稍微修改一下逻辑。您应该创建一个 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()来识别单词和字符