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
代替,也就是行数。我们通过拆分字符串得到行数。
第二个%d
被Stream.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.Pattern
和java.util.Matcher
并使用它matcher.find()
来识别单词和字符
我正在尝试从文件中读入文字。我需要计算文本文件中的字数、行数和字符数。字数应该只包括单词(只包含字母,没有标点符号、空格或非字母字符)。字符数应仅包括这些单词中的字符。
这就是我目前所拥有的。我不确定如何计算字符。每次我 运行 程序,只要我输入文件名,它就会跳转到 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
代替,也就是行数。我们通过拆分字符串得到行数。
第二个%d
被Stream.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.Pattern
和java.util.Matcher
并使用它matcher.find()
来识别单词和字符