below is my code for a homework assignment where I need to read the contents of an external file and determine the number of words within it, number of 3-letter words, and percentage of total. I've got that part down just fine, but I also have to print the external file's contents prior to displaying the above information. Below is my current code:
public class Prog512h
{
public static void main( String[] args)
{
int countsOf3 = 0;
int countWords = 0;
DecimalFormat round = new DecimalFormat("##.00"); // will round final value to two decimal places
Scanner poem = null;
try
{
poem = new Scanner (new File("prog512h.dat.txt"));
}
catch (FileNotFoundException e)
{
System.out.println ("File not found!"); // returns error if file is not found
System.exit (0);
}
while (poem.hasNext())
{
String s = poem.nextLine();
String[] words = s.split(" ");
countWords += words.length;
for (int i = 0; i < words.length; i++)
{
countsOf3 += words[i].length() == 3 ? 1 : 0; // checks for 3-letter words
}
}
while(poem.hasNext())
{
System.out.println(poem.nextLine());
}
System.out.println();
System.out.println("Number of words: " + countWords);
System.out.println("Number of 3-letter words: " + countsOf3);
System.out.println("Percentage of total: " + round.format((double)((double)countsOf3 / (double)countWords) * 100.0)); // converts value to double and calculates percentage by dividing from total number of words
}
}
The statement
while(poem.hasNext())
{
System.out.println(poem.nextLine());
}
is supposed to print the external file's contents. However, it doesn't. When I try moving it before my prior while loop, it prints, but screws up my printed values for the # of words, 3-letter words, percentage, etc. I'm not really sure what the issue is here. Could someone provide some assistance?
Thank you in advance.
Your scanner is trying to reread the file but it is at the bottom so there are no more lines to read. You have two options:
Option 1
Create a new Scanner object for the same file (to start at the beginning again) and then call your while loop on that file (works, but not a great design).
Scanner poem2 = null;
try
{
poem2 = new Scanner (new File("prog512h.dat.txt"));
}
catch (FileNotFoundException e)
{
System.out.println ("File not found!"); // returns error if file is not found
System.exit (0);
}
while(poem2.hasNext())
{
System.out.println(poem2.nextLine());
}
Option 2
A better option would be to display each line as you read it in. This can be accomplished by adding an extra line to the already existent while loop:
while (poem.hasNext())
{
String s = poem.nextLine();
System.out.println(s); // <<< Display each line as you process it
String[] words = s.split(" ");
countWords += words.length;
for (int i = 0; i < words.length; i++)
{
countsOf3 += words[i].length() == 3 ? 1 : 0; // checks for 3-letter words
}
}
This only requires one Scanner object and only requires one read-through of the file which is much more efficient.
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
I am pretty new to Java and I cannot seem to figure out why I am getting this error message relating to this error message: File not found. Exception in thread "main" java.lang.NullPointerException at Project1.main(Project1.java:24). Any help would be appreciated. I have tried running through command prompt as well as an online java compiler and both tell me that there is not a file to be found.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Project1 {
public static void main(String[] args)
{
// create file object
File file = new File("input.txt");
// create a scanner object
Scanner scan = null;
try
{
scan = new Scanner(file);
}
catch (FileNotFoundException e)
{
System.out.println("File not found.");
}
// take number of men or women from file - first line
int num = scan.nextInt();
// create string array of size number of men to save men preference
String[] menPreferenceArray = new String[num];
// create string array of size number of women to save women preference
String[] womenPreferenceArray = new String[num];
// point to next line
scan.nextLine();
// loop till 2*num lines
for (int i = 0; i < 2 * num; i++)
{
// take first 3 preference and save to men preference array
if (i < num)
menPreferenceArray[i] = scan.nextLine();
else
// take next 3 preference and save to women preference array
womenPreferenceArray[i - num] = scan.nextLine();
}
// variable to count prefectMatch
int perfectPairNum = 0;
// read till file has next line
while (scan.hasNext())
{
// take a marriage pair as string
String marriage = scan.nextLine();
// split by space
String[] pair = marriage.split(" ");
// reverse the pair
String marriageReverse = pair[1] + " " + pair[0];
// count variable to check if men and women has same preference
int count = 0;
// loop through the men and women preference array
for (int j = 0; j < 2 * num; j++)
{
if (j < num)
{
// take first preference string using substring and check if the marriage pair
// is equal to preference string
if (menPreferenceArray[j].substring(0, 3).equals(marriage))
// increment count by 1
count++;
} else
{
// take first preference string using substring
if (womenPreferenceArray[j - num].substring(0, 3).equals(marriageReverse)) {
// increment count by 1
count++;
}
}
}
// if count equal to 2 means, both men and women have same preference, so
// marriage is stable
if (count == 2)
{
// increment variable to check all marriages are stable
perfectPairNum++;
}
else
{
// if count not equal to 2 means, both men or women do not have same preference
// . so marriage is unstable
System.out.println("Unstable " + marriage);
}
}
// close scanner object
scan.close();
// if all marriages are stable, then output stable
if (perfectPairNum == num)
{
System.out.println("Stable");
}
}
}
Don't just print a message when you catch an exception and continue on.
Here you catch the FileNotFoundException cause "input.txt" does not exist (at least not in the current directory). You print a message but still try to use scan, which never got initialized, as its constructor threw. So scan is null, and that's why you get the NullPointerException when you use scan.
To fix this, exit the program when you catch the exception. Since you need that input file, there's no way to continue without it.
Either change the catch block:
Scanner scan = null;
try
{
scan = new Scanner(file);
}
catch (FileNotFoundException e)
{
System.out.println("File not found.");
return; // Exit the program
}
Or don't catch the exception at all and declare that main can throw FileNotFoundException. In this case the program will error out for you.
public static void main(String[] args) throws FileNotFoundException
{
// ...
scan = new Scanner(file);
// ...
To avoid an error with files, specify the absolute path to the file, e.g, "/home/me/input.txt" or "C:\\Users\\me\\input.txt" instead of just "input.txt".
If input.txt doesn't already exist, you can create it like so:
File file = new File("input.txt");
file.createNewFile();
Here is a link to the docs: https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createNewFile()
I have been stuck for some time now. In my code, I want to read all of the names I have from a separate file, and I want to allow the user to select how many names they want to save to a new separate file and allow them to select which names they want to save to the file (by selecting the number in-front of the names printed to the screen).
I am not sure on how I would allow the user to select certain positions in the array "names" to print to a new file. My idea was to use the array "select" and check what number was in that array (eg select[0] = 1) and print out number[1].
Any help would be much appreciated, thankyou!
public class Main {
public static void main(String[] args) throws IOException {
BufferedWriter writefile;
BufferedReader readfile;
Scanner scan = new Scanner(System.in);
readfile = new BufferedReader(new FileReader("names.txt"));
writefile = new BufferedWriter(new FileWriter("nameChoices.txt"));
String names[] = new String[10];
System.out.println("Here are the list of names:");
System.out.println();
for (int i = 0; i < 10; i++) {
names[i] = readfile.readLine();
System.out.println(i + ". " + names[i]);
}
System.out.println();
System.out.println("Please enter the number of names you want to select:");
int choice = scan.nextInt();
System.out.println("Enter the number infront of the names you want to select: ");
int select[] = new int[choice];
for (int j = 0; j < choice; j++) {
select[j] = scan.nextInt();
}
}
}
Your Question: "I am not sure on how I would allow the user to select certain positions in the array "names" to print to a new file."
There is nothing wrong with the way you have already opted to do this other than perhaps letting the User know what selection they happen to be currently on and trapping for invalid entries such as values too high or too low and of course alpha characters where numerical characters are required. Without taking care of this business you leave things open to specific Error Exceptions. When asking the User for input a good solution would be for you to take care of what can go wrong and if it does, allow the User to re-enter the required data.
The biggest problem you have is that you have no mechanism in place to write the desired data to file. You've started by declaring a BufferedWriter object but you have yet to implement it. This would of course entail iterating through the select array which ultimately each element holds the index of the names desired to save to file. Simply iterate through the select array and write each name to file:
for (int i = 0; i < select.length; i++) {
writefile.write(name[select[i]] + System.lineSeparator());
writefile.flush();
}
// Close the file when all writing is done.
writefile.close();
With what is discussed above you might have a solution that would look something like this:
try {
BufferedWriter writefile = new BufferedWriter(new FileWriter("nameChoices.txt"));
BufferedReader readfile = new BufferedReader(new FileReader("names.txt"));
Scanner scan = new Scanner(System.in);
String allNames = "", fileLine = "";
while((fileLine = readfile.readLine()) != null) {
// Using a 'Terary Operator' to fill the allNames variable
// with a comma delimited string of all the names in file. It
// doesn't matter how many names are in file.
allNames+= (allNames.equals("")) ? fileLine : "," + fileLine;
}
// Split the string in allNames to the names array.
String names[] = allNames.split(",");
// Display the names in console:
// Use the System.out.format() method
// to create a columnar display.
System.out.println("Here are the list of names:");
for (int i = 0; i < names.length; i++) {
// Use the modulus operator to ensure 4 columns
if (i % 4 == 0){
// Print a new line
System.out.print("\n");
}
System.out.format("%-15s", (i+1) + ". " + names[i]);
}
readfile.close(); // Close the reader. Don't need to leave it open.
System.out.println();
// Get the number of names the User wants to save...
int choice = 0;
while (choice == 0) {
System.out.println("\nPlease enter the number of names you want to select:");
try {
choice = scan.nextInt();
}
catch (InputMismatchException ex) {
System.err.println("Invalid Entry! Numerical value Only!\n");
scan.nextLine(); // Clear the scanner buffer
choice = 0;
}
}
// Get the actual names the User wants to save...
System.out.println();
int j = 0;
int select[] = new int[choice];
System.out.println("Enter the numbers in front of the names you want to select: ");
while (j < choice) {
System.out.println("Enter the number for name #" + (j+1) + ": ");
try {
int index = scan.nextInt();
if (index < 1 || index > names.length) {
throw new InputMismatchException();
}
select[j] = index;
j++;
}
catch (InputMismatchException ex) {
System.err.println("Invalid Entry! Numerical value Only (1 to " +
names.length + ")!\n");
scan.nextLine(); // Clear the scanner buffer
}
}
//Write choices to file and Console...
System.out.print("\nSaving Names: ");
for (int i = 0; i < select.length; i++) {
String save = names[select[i]-1] ;
System.out.print(save + "\t");
writefile.write(save + System.lineSeparator());
writefile.flush();
}
writefile.close(); // close the writer
System.out.println("\nDONE! File Created!");
}
catch (IOException ex) { ex.printStackTrace(); }
In this example invalid entries are taken care of and the User is given the chance to enter valid data.
So I'm pretty new to Java and I'm working on a code that is supposed to read a .txt file that the user inputs and then ask the user for a word to search for within the .txt file. I'm having trouble figuring out how to count the amount of times the inputted word shows up in the .txt file. Instead, the code I have is only counting the amount of lines the code shows up in. Can anyone help me figure out what to do to have my program count the amount of times the word shows up instead of the amount of lines the word shows up in? Thank you! Here's the code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TextSearch {
public static void main(String[] args) throws FileNotFoundException {
Scanner txt;
File file = null;
String Default = "/eng/home/tylorkun/workspace/09.1/src/Sample.txt";
try {
txt = new Scanner(System.in);
System.out.print("Please enter the text file name or type 'Default' for a default file. ");
file = new File(txt.nextLine());
txt = new Scanner(file);
while (txt.hasNextLine()) {
String line = txt.nextLine();
System.out.println(line);
}
txt.close();
} catch (Exception ex) {
ex.printStackTrace();
}
try {
txt = new Scanner(file);
Scanner in = new Scanner(System.in);
in.nextLine();
System.out.print("Please enter a string to search for. Please do not enter a string longer than 16 characters. ");
String wordInput = in.nextLine();
//If too long
if (wordInput.length() > 16) {
System.out.println("Please do not enter a string longer than 16 characters. Try again. ");
wordInput = in.nextLine();
}
//Search
int count = 0;
while (txt.hasNextLine()) //Should txt be in?
{
String line = txt.nextLine();
count++;
if (line.contains(wordInput)) //count > 0
{
System.out.println("'" + wordInput + "' was found " + count + " times in this document. ");
break;
}
//else
//{
// System.out.println("Word was not found. ");
//}
}
} catch (FileNotFoundException e) {
System.out.println("Word was not found. ");
}
} //main ends
} //TextSearch ends
Since the word doesn't have to be standalone, you can do an interesting for loop to count how many times your word appears in each line.
public static void main(String[] args) throws Exception {
String wordToSearch = "the";
String data = "the their father them therefore then";
int count = 0;
for (int index = data.indexOf(wordToSearch);
index != -1;
index = data.indexOf(wordToSearch, index + 1)) {
count++;
}
System.out.println(count);
}
Results:
6
So the searching segment of your code could look like:
//Search
int count = 0;
while (txt.hasNextLine())
{
String line = txt.nextLine();
for (int index = line.indexOf(wordInput);
index != -1;
index = line.indexOf(wordInput, index + 1)) {
count++;
}
}
System.out.println(count);
Your problem is that you are incrementing count on each line, regardless of whether the word is present. Also, you have no code to count multiple matches per line.
Instead, use a regex search to find the matches, and increment count for each match found:
//Search
int count = 0;
Pattern = Pattern.compile(wordInput, Pattern.LITERAL | Pattern.CASE_INSENSITIVE);
while(txt.hasNextLine()){
Matcher m = pattern.matcher(txt.nextLine());
// Loop through all matches
while (m.find()) {
count++;
}
}
NOTE: Not sure what you are using this for, but if you just need the functionality you can combine the grep and wc (wordcount) command-line utilities. See this SO Answer for how to do that.
I was given a homework in which I need to count the number of words in a file and output how many words are the same. Like "a" in the whole text maybe it was repeated 350 times. I hope you get my point.
Now, im trying to do some tests and created a file("test.txt") containing:
Im a good boy
Hello World
A happy world it is
What I'm trying to do is storing it into an array to be able to count the words in the file. But I'm having a hard time. This is what i got so far.
void readFile() {
System.out.println("Gi navnet til filen: ");
String filNavn = sc.next();
File k = new File(filNavn);
try {
Scanner sc2 = new Scanner(k);
while (sc2.hasNextLine()) {
String line = sc2.nextLine();
String[] m = line.split(" ");
String x = m[0];
System.out.println(x);
}
} catch (FileNotFoundException e) {
System.out.print("mmm");
}
}
but this only outputs the first words on the line.
What I would like to see is the same as the text file. But stored in an array. How can I do it?
Im a good boy
Hello World
A happy world it is
This will only print out the first word because of this
String[] m = line.split(" ");
String x = m[0];
System.out.println(x);
Here you are only assigning the first word in the array (created by your split) to the variable x and then printing only that word.
To print all the words you will need to loop the array like so
for(int i = 0; i < m.length; i++)
{
System.out.println(m[i]);
}
And to print the same as the file you could use System.out.print(). Note you will need to put the spaces back in and also account for the new lines. Below is one approach:
for(int i = 0; i < m.length; i++)
{
if(i == m.length - 1)
System.out.print(m[i] + "\n");
else
System.out.print(m[i] + " ");
}
Since your post didn't say you HAD to do it in Java (although I am guessing that is the case), I offer this:
perl -e 'while(<STDIN>) { map { $w->{lc($_)}++; } split("\\s", $_); } map { print "$_ $w->{$_}\n"; } keys %{$w} ;' < test.txt
File folder2 = new File("C:\\Users\\user\\fypworkspace\\TextRenderer");
File[] listOfFiles2 = folder.listFiles();
System.out.println("Please enter the required word :");
Scanner scan2 = new Scanner(System.in);
String word2 = scan.nextLine();
String [] array2 = word2.split(" ");
{
for (int i=0; i < listOfFiles.length; i++)
{
if ((listOfFiles2[i].getName().endsWith(".txt")))
{
try
{
BufferedReader in= new BufferedReader(new FileReader(listOfFiles2[i].getName()));
int numDoc = 0;
Scanner s2 = new Scanner(listOfFiles2[i].getName());
{
while (s2.hasNext())
{
if (s2.next().equals(word2)) numDoc++;
}
System.out.println("The number of document containing the term is " + numDoc);
}
in.close();
} catch (IOException e) {
}
This is my code for counting the number of documents that contain a specific term.
Every time the program finds a specific term inside the document, it will increment numDoc counter.
This code does not do anything, however. What am I doing wrong?
Add System.out.println() throughout your code to output important information for debugging.
Not directly related but you can use a enhance for loop to loop through the files. See: http://download.oracle.com/javase/tutorial/java/nutsandbolts/for.html
Your System.out.println for your total is inside your loop and it should be outside after you have finished looping through all the documents.
(And maybe the most important) You are not handling your IOException. At the least printout a stack trace or the message from the exception.