我正在尝试从文件中读取单词。我需要计算文本文件中的单词,行和字符。字数统计应仅包括字(仅包含字母,标点,空格或非字母字符)。字符数应只包括这些单词中的字符。
这是我到目前为止所拥有的。我不确定如何计算字符。每次我运行该程序时,只要输入文件名,它就会跳到catch机制(并且文件路径应该没有问题,就像我之前尝试过的那样)。我试图在没有try / catch的情况下创建程序,以查看错误是什么,但是没有它就无法工作。
为什么输入文件名时它会跳转到catch功能?如何修复此程序以正确计算文本文件中的单词,行和字符?
答案 0 :(得分: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.Pattern
和java.util.Matcher
并使用matcher.find()
来识别单词和字符
答案 1 :(得分:0)
我尝试了您的代码,但这里没有收到任何异常。但是,我怀疑当您输入文件名时,也许您忘记了文件的扩展名。
答案 2 :(得分:-1)
您可能在输入时忘记了文件扩展名,但是这样做的方法要简单得多。您还提到您不知道如何计算字符。您可以尝试这样的事情:
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)
有点多余。