I'm trying to write a Java program to analyse each string in a string array from a text file and if the number parses to a double, the program prints the word previous to it and the word after. I can't seem to find out how to parse each element of a string array. Currently it will only print the first number and the following word but not the previous word. Hopefully somebody can help.
My text file is as follows:
Suppose 49 are slicing a cake to divide it between 5 people. I cut myself a big slice, consisting of 33.3 percent
of the whole cake. Now it is your turn to cut a slice of cake. Will you also cut a 33.3 percent slice? Or will you
be fairer and divide the remaining 66.6 percent of the cake into 4 even parts? How big a slice will you cut?
Here is my code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class NumberSearch {
public static void main(String args[]) throws FileNotFoundException {
//creating File instance to reference text file in Java
// String filedirect = JOptionPane.showInputDialog(null, "Enter your file");
File text = new File("cakeQuestion2.txt");
//Creating Scanner instance to read File in Java
Scanner scnr = new Scanner(text);
//Reading each line of file using Scanner class
int lineNumber = 1;
while(scnr.hasNextLine())
{
String line = scnr.nextLine();
lineNumber++;
//Finding words
String[] sp = line.split(" +"); // "+" for multiple spaces
for (int i = 1; i < sp.length; i++)
{
{
double d = Double.parseDouble(sp[i]);
// System.out.println(+ d);
if (isDouble(sp[i]))
{
// have to check for ArrayIndexOutOfBoundsException
String surr = (i-2 > 0 ? " " + sp[i-2]+" " : "") +
sp[i] +
(i+1 < sp.length ? " "+sp[i+1] : "");
System.out.println(surr);
}
}}
}
}
public static boolean isDouble( String str )
{
try{
Double.parseDouble( str );
return true;
}
catch( Exception e ){
return false;
}}}
Mmmmm... your code seems too verbose and complex for the mission.
Check this snippet:
public static void main(String args[]) throws FileNotFoundException {
String line = "Suppose 49 are slicing a cake to divide it between 5 people. I cut myself a big slice, consisting of 33.3 percent of the whole cake. Now it is your turn to cut a slice of cake. Will you also cut a 33.3 percent slice? Or will you be fairer and divide the remaining 66.6 percent of the cake into 4 even parts? How big a slice will you cut?";
String[] sp = line.split(" +"); // "+" for multiple spaces
final String SPACE = " ";
// loop over the data
for (int i = 0; i < sp.length; i++) {
try {
// if exception is not raised, IS A DOUBLE!
Double.parseDouble(sp[i]);
// if is not first position print previous word (avoid negative index)
if (i > 0)
System.out.print(sp[i - 1] + SPACE);
// print number itself
System.out.print(sp[i] + SPACE);
// if is not last position print previous word (avoid IOOBE)
if (i < sp.length - 1)
System.out.print(sp[i + 1]);
// next line!
System.out.println();
} catch (NumberFormatException ex) {
// if is not a number, not our problem!
}
}
}
RESULT:
Suppose 49 are
between 5 people.
of 33.3 percent
a 33.3 percent
remaining 66.6 percent
into 4 even
Related
I'm trying to figure out if I can count the characters of each token and display that information such as:
day is tokenized and my output would be: "Day has 3 characters." and continue to do that for each token.
My last loop to print out the # of characters in each token never prints:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> tokenizedInput = new ArrayList<>();
String sentenceRetrieved;
// getting the sentence from the user
System.out.println("Please type a sentence containing at least 4 words, with a maximum of 8 words: ");
sentenceRetrieved = sc.nextLine();
StringTokenizer strTokenizer = new StringTokenizer(sentenceRetrieved);
// checking to ensure the string has 4-8 words
while (strTokenizer.hasMoreTokens()) {
if (strTokenizer.countTokens() > 8) {
System.out.println("Please re-enter a sentence with at least 4 words, and a maximum of 8");
break;
} else {
while (strTokenizer.hasMoreTokens()) {
tokenizedInput.add(strTokenizer.nextToken());
}
System.out.println("Thank you.");
break;
}
}
// printing out the sentence
System.out.println("You entered: ");
System.out.println(sentenceRetrieved);
// print out each word given
System.out.println("Each word in your sentence is: " + tokenizedInput);
// count the characters in each word
// doesn't seem to run
int totalLength = 0;
while (strTokenizer.hasMoreTokens()) {
String token;
token = sentenceRetrieved;
token = strTokenizer.nextToken();
totalLength += token.length();
System.out.println("Word: " + token + " Length:" + token.length());
}
}
}
Example of Console:
Please type a sentence containing at least 4 words, with a maximum of 8 words:
Hello there this is a test
Thank you.
You entered:
Hello there this is a test
Each word in your sentence is: [Hello, there, this, is, a, test]
First off, I have added the necessary imports and built a class around this main method. This should compile.
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;
public class SOQ_20200913_1
{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> tokenizedInput = new ArrayList<>();
String sentenceRetrieved;
// getting the sentence from the user
System.out.println("Please type a sentence containing at least 4 words, with a maximum of 8 words: ");
sentenceRetrieved = sc.nextLine();
StringTokenizer strTokenizer = new StringTokenizer(sentenceRetrieved);
// checking to ensure the string has 4-8 words
while (strTokenizer.hasMoreTokens()) {
if (strTokenizer.countTokens() > 8) {
System.out.println("Please re-enter a sentence with at least 4 words, and a maximum of 8");
break;
} else {
while (strTokenizer.hasMoreTokens()) {
tokenizedInput.add(strTokenizer.nextToken());
}
System.out.println("Thank you.");
break;
}
}
// printing out the sentence
System.out.println("You entered: ");
System.out.println(sentenceRetrieved);
// print out each word given
System.out.println("Each word in your sentence is: " + tokenizedInput);
// count the characters in each word
// doesn't seem to run
int totalLength = 0;
while (strTokenizer.hasMoreTokens()) {
String token;
token = sentenceRetrieved;
token = strTokenizer.nextToken();
totalLength += token.length();
System.out.println("Word: " + token + " Length:" + token.length());
}
}
}
Next, let's look at this working example. It seems like everything up until your final while loop (the one that counts character length) works just fine. But if you notice, the while loop before the final one will continue looping until it has no more tokens to fetch. So, after it has finished gathering all of the tokens and has no more tokens to gather, you try and create the final while loop, asking it to gather more tokens. It would not have reached the while loop until it ran out of tokens to gather!
Finally, in order to solve this, you can simply go through the list that you added to in the second to last while loop, and simply cycle through that for your final loop!
For example:
int totalLength = 0;
for (String each : tokenizedInput) {
totalLength += each.length();
System.out.println("Word: " + each + " Length:" + each.length());
}
When i run the following program I get an error at line 20, and this is my code:
package J1;
import java.util.Scanner;
public class SpeedLimit {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int input = keyboard.nextInt();
String[] tab = new String[2];
String output="";
int speed = 0;
while(input!=-1){
int last =0;
for (int i=0; i<input ; i++){
String pair = keyboard.next();
tab = pair.split(" ");
speed = speed + Integer.parseInt(tab[0])*(Integer.parseInt(tab[1])-last);
last = Integer.parseInt(tab[1]);
}
output = output +speed + "miles" + "\n";
speed =0;
input = Integer.parseInt(keyboard.nextLine());
}
System.out.println(output);
}
}
when i run the code, I enter the following input from the keyboard:
3
20 2
30 6
10 7
2
60 1
30 5
4
15 1
25 2
30 3
10 5
-1
to get this result as an output:
170 miles
180 miles
90 miles
but i get the following Error when i run the code
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at J1.SpeedLimit.main(SpeedLimit.java:20)
String pair = keyboard.next(); This reads only one token which are separated by " " so when you split pair by " ". It will only have one element, The String itself. So you need to read the whole line and then split it by delimited " ".
Another mistake is that when you change that line with String pair = keyboard.nextLine(); , You will still get error because System considers Enter key as input of .nextLine() method. So you need to discard that extra unnecessary input.
while(input!=-1){
int last =0;
for (int i=0; i<input ; i++){
int ip1=keyboard.nextInt();
int ip2=keyboard.nextInt();
speed = speed + ip1*(ip2-last);
last = ip2;
}
output = output +speed + "miles" + "\n";
speed =0;
input = keyboard.nextInt();
}
You are reading the variable pair the wrong way and then you split it and assign it to tab which fails to automatically to fetch index cause pair variable got a problem.
*nextLine(): reads the remainder of the current line even if it is empty.
keyboard.nextLine(); //To avoid the exception you commented
String pair = keyboard.nextLine(); //here is solved
tab = pair.split(" ");
Keyboard.next() will only read the input till the space, so pair and the array will have only one number, so tab[1] results in arrayOutOfBound exception. Use the method nextLine() to read the inputs with space.
You Can try below changes in your code :
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int input = Integer.parseInt(keyboard.nextLine());
String[] tab = new String[2];
String output="";
int speed = 0;
while(input!=-1){
int last =0;
for (int i=0; i<input ; i++){
String pair = keyboard.nextLine();
tab = pair.split(" ");
speed = speed + Integer.parseInt(tab[0].trim())*(Integer.parseInt(tab[1].trim())-last);
last = Integer.parseInt(tab[1]);
}
output = output +speed + " miles " + "\n";
speed =0;
input = Integer.parseInt(keyboard.nextLine());
}
System.out.println(output);
}
i did'n really understand how you are providing the inputs. but, if "3" happens to be your first line then split(" ") would return an array of length 1. thus, tab[0] would return 3 and tab[1] will give you a nullPointerException.
try adding an check for the length of tab before executing your line 20.
this should do the trick:
if(tab.length() > 1){
speed = speed + Integer.parseInt(tab[0])*(Integer.parseInt(tab[1])-last);
}
I have stored two text files into two separate arrays. Now, I am trying to compare both arrays to find duplicate values. I am having issues with my logic, and I am unable to print out the number of times a duplicate value appears.
file1 contains:
1913 2016 1 1913 186
2016 1711 32843 2016 518
3 1913 32843 32001 4
250 5 3500 6 7
8 27 73 9 10
1711 73 11 2 1.4
1.4 12 33.75278 84.38611 1913
19 1930 20 21 1947
22 1955 23 1961 23
1969 27 1995 26 27
1962 28 29 30 1970
31 31
file2 contains:
1913 2016 32843 31 27 1.4 4 7 2 23
I am trying to find values in file2 that are duplicated in file1, and how many times.
I have the following code:
public static void findDuplicates() {
// array for first file
for (int n = 0; n < nums.size(); n++) {
// matches are false by default
boolean match = false;
int count = 0;
String v = nums.get(n);
// array for second file
for (int k = 0; k < nums1.size(); k++) {
String p = nums1.get(k);
// second file contains values from first file
if (p.contains(v)) {
// there is a match
match = true;
// when there is a match print out matched values and the number of times they appear in second file
if (match) {
count++;
System.out.println( p + " " + "is duped" + " " + count + " " + "times");
}
}
}
}
}
When I compile and run this code, this is the output:
31 is duped 1 times
Could someone let me know what I am doing wrong here?
EDIT
Here is the rest of my code:
public static ArrayList<String> nums;
public static ArrayList<String> nums1;
//Create a main method to start the program.
//Add FileNot FoundException in case the file can't be found by computer.
public static void main(String[] args) throws FileNotFoundException{
//The while will help us read the content into our computer piece by piece. It will not stop until the end of assignment.csv.
while(FILE1.hasNext()){
//Create a String variable - TempString. We use TempString to store each piece temporarily.
String TempString = FILE1.next();
String temp1 = TempString.replaceAll("[\\,]", "");
String pattern1 = "[0-9]+\\.{1}[0-9]+";
//Compile the Regular Expression into Pattern and store it in r1 so that the computer can understand the Regular Expression.
Pattern r1 = Pattern.compile(pattern1);
Matcher m1 = r1.matcher(temp1);
String pattern2 = "[0-9]+";
//Compile the Regular Expression into Pattern and store it in r2 so that the computer can understand the Regular Expression.
Pattern r2 = Pattern.compile(pattern2);
Matcher m2 = r2.matcher(temp1);
nums = new ArrayList<String>();
//Recollect, m1 is used to match decimal numbers.
if(!(m1.find())){//if a decimal number CAN'T be found
//We use while statement instead of if statement here.
//If there is only one piece per line, we can use either while statement or if statement.
//However, we have to use while statement if there is more than one piece per line.
while(m2.find()) {//if an integer number CAN be found
//If an Integer is found, we add 1 to Variable count.
count++;
//Even though the number (i.e., m2.group(0)) is an Integer, its data type is String. So we store it to a String variable - number.
String number = m2.group(0);
nums.add(number);
//If the remainder of count by 5 is zero, we display the number and advance to a new line.
if (count % 5 == 0){
System.out.println(number);
}
//Otherwise, we just display the number on the same line and divide numbers by a space.
else
System.out.print(number + " ");
}
}
//If we find a decimal number
else{
//We add 1 to Variable count.
count++;
//Even though the number (i.e., m1.group(0)) is a decimal number, its data type is String. So we store it to a String variable - number.
String number = m1.group(0);
nums.add(number);
//If the remainder of count by 5 is zero, we display the number and advance to a new line.
if (count % 5 == 0) {
System.out.println(number);
}
//Otherwise, we just display the number on the same line and divide numbers by a space.
else
System.out.print(number + " ");
}
}
FILE1.close();//Once we finish the task, we close the file.
while(FILE2.hasNext()){
//Create a String variable - TempString. We use TempString to store each piece temporarily.
String TempString = FILE2.next();
//So I use replaceAll function to eliminate comma (,) and store the new string in temp1.
String temp1 = TempString.replaceAll("[\\,]", "");
String pattern1 = "[0-9]+\\.{1}[0-9]+";
//Compile the Regular Expression into Pattern and store it in r1 so that the computer can understand the Regular Expression.
Pattern r1 = Pattern.compile(pattern1);
//Match the Regular Expression with the piece (temp1) we read from assignment.csv.
Matcher m1 = r1.matcher(temp1);
String pattern2 = "[0-9]+";
//Compile the Regular Expression into Pattern and store it in r2 so that the computer can understand the Regular Expression.
Pattern r2 = Pattern.compile(pattern2);
//Match the Regular Expression with the piece (temp1) we read from assignment.csv.
Matcher m2 = r2.matcher(temp1);
nums1 = new ArrayList<String>();
//We have two types of numbers - Integer and Decimal
//Let's start us Integer.
//Recollect, m1 is used to match decimal numbers.
if(!(m1.find())){//if a decimal number CAN'T be found
//We use while statement instead of if statement here.
//If there is only one piece per line, we can use either while statement or if statement.
//However, we have to use while statement if there is more than one piece per line.
while(m2.find()) {//if an integer number CAN be found
//If an Integer is found, we add 1 to Variable count.
count++;
//Even though the number (i.e., m2.group(0)) is an Integer, its data type is String. So we store it to a String variable - number.
String number = m2.group(0);
nums1.add(number);
//If the remainder of count by 5 is zero, we display the number and advance to a new line.
if (count % 5 == 0){
//System.out.println(number);
}
//Otherwise, we just display the number on the same line and divide numbers by a space.
else
System.out.println(/*number + " "*/);
}
}
//If we find a decimal number
else{
//We add 1 to Variable count.
count++;
//Even though the number (i.e., m1.group(0)) is a decimal number, its data type is String. So we store it to a String variable - number.
String number = m1.group(0);
nums1.add(number);
//If the remainder of count by 5 is zero, we display the number and advance to a new line.
if (count % 5 == 0){
//System.out.println(number);
}
//Otherwise, we just display the number on the same line and divide numbers by a space.
else
System.out.println(/*number + " "*/);
}
findDuplicates();
}
FILE2.close();//Once we finish the task, we close the file.
}
I tried to delete as much unnecessary code as I could.
EDIT
Expected output should be:
1913 is duplicated 3 times.
2016 is duplicated 2 times.
32843 is duplicated 1 times.
31 is duplicated 2 times.....
EDIT
So I believe i've found the problem. For some reason,
String p = nums.get(k)
in my findDuplicates() method is only returning the value 31, and not the other values. I am working on solving the problem, and will post an answer when I do.
I think the biggest issue is that the printline is inside the second for loop.Furthermore I would remove the boolean and just compare the 2 Strings (p==v).
So the code would look more like this:
public static void main(String[] args) {
// array for second file
for (int n = 0; n < nums1.size(); n++) {
// matches are false by default
int count = 0;
String v = nums1.get(n);
// array for first file
for (int k = 0; k < nums.size(); k++) {
String p = nums.get(k);
// second file contains values from first file
if (p==v) {
count++;
}
}
System.out.println( v + " " + "is duped" + " " + count + " " + "times");
}
}
}
With the changes I made the code runs as intended.You can check out a live demo here.
Output:
1913 is duped 4 times
2016 is duped 3 times
32843 is duped 2 times
31 is duped 2 times
27 is duped 3 times
1.4 is duped 2 times
4 is duped 1 times
7 is duped 1 times
2 is duped 1 times
23 is duped 2 times
You should use the System.out.println statement outside inner loop so that first whole of second arraylist get iterated before number of times the number is duplicated is printled.
You also need to make a few other changes to run the program correctly
for (int n = 0; n < nums.size(); n++) {
// matches are false by default
boolean match = false;
int count = 0;
String v = nums.get(n);
// array for second file
for (int k = 0; k < nums1.size(); k++) {
String p = nums1.get(k);
// second file contains values from first file
if (p.contains(v)) {
// there is a match
match = true;
// when there is a match print out matched values and the number of times they appear in second file
if (match) {
count++;
match = false;
}
}
System.out.println( p + " " + "is duped" + " " + count + " " + "times");
count = 0;
}
}
But still then your logic will not work all case because you are not comparing how many times a number is repeated in first file. You are only comparing second file numbers with first file ones. For the case which you gave in question interchanging the two files after modifying the code as I have mentioned it will work.
please try it on.
package stackoverflow.test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test {
public List<Integer> list = new ArrayList<Integer>();
public List<Integer> dup = new ArrayList<Integer>();
public Map<Integer, Integer> hashDup = new HashMap<Integer, Integer>();
public void fileReader() {
File file = new File("/home/john/Documents/file1.txt");
List<Integer> list1 = this.output(file);
File file2 = new File("/home/john/Documents/file2.txt");
List<Integer> list2 = this.output(file2);
for (int i = 0; i < list1.size(); i++) {
int counter = 0;
for (int j = 0; j < list2.size(); j++) {
if (list1.get(i) == list2.get(j)) {
counter++;
}
}
if (!hashDup.containsKey(list1.get(i))) {
hashDup.put(list1.get(i), counter);
System.out.println(" dup " + list1.get(i) + " :" + counter);
}
}
}
public List<Integer> output(File file) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String text = null;
while ((text = reader.readLine()) != null) {
// System.out.println( text);
String[] str = text.split(" ");
for (String string : str) {
list.add(Integer.parseInt(string));
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
}
}
// print out the list
// System.out.println(list.toString());
return list;
}
public static void main(String args[]) {
Test t = new Test();
t.fileReader();
}
}
I need to do a simple program that counts the number of words and gives the total of the numbers in a text file. The program has to compute the sum and average of all the numbers. The average is the sum divided by the count.The file counts the numbers and words together. It just prints 34.
//CAT DOG BIRD FISH
//1 2 3 4 5
//TURTLE LIZARD SNAKE
//6 7 8 9 10
//FISH SHARK
//11 12 13 14 15
//SPIDER FLY GRASSHOPPER ANT SCORPION
//16 17 18 19 20
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class HomeWork8 {
public static void main(String[] args) throws IOException {
String words, numbers, message;
int numberWords = 0, countNumber = 0;
FileInputStream fis = new FileInputStream("/Users/ME/Documents/Words and Numbers.txt");
Scanner in = new Scanner(fis);
while (in.hasNext()) {
words = in.next();
numberWords++;
}
while (in.hasNext()) {
in.useDelimiter("");
numbers = in.next();
countNumber++;
}
in.close();
message = "The number of words read from the file was " + numberWords
+ "\nThe count of numbers read from the file was" + countNumber;
JOptionPane.showMessageDialog(null, message);
}
}
String pattern ="\\d";
String word="shdhdshk 46788 jikdjsk 9 dsd s90 dsds76";
Matcher m = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(word);
int count=0;
while (m.find()) {
count++;
}
System.out.println(count);
If you need to get the single number character count you can use \d . But If you are interested in whole number occurrence then you have to use \d+ instead of \d. Ex: 46788,9,90,76
You can even use regular expressions to filter the words and numbers as is shown below:
public static void main(String[] args) throws IOException {
String words, message;
int numberWords = 0, countNumber = 0;
FileInputStream fis = new FileInputStream("src/WordsandNumbers.txt");
Scanner in = new Scanner(fis);
String numRegex = ".*[0-9].*";
String alphaRegex = ".*[A-Za-z].*";
while (in.hasNext()) {
words=in.next();
if (words.matches(alphaRegex)) {
numberWords++;
}
else if(words.matches(numRegex))
{
countNumber++;
}
}
in.close();
message = "The number of words read from the file was " + numberWords
+ "\nThe count of numbers read from the file was" + countNumber;
System.console().writer().println(message);
}
You need to have a single iteration through the content of the filerather than having 2 while loops.
Just before the second while (in.hasNext()) { you should reset the stream by adding the following code:
in = new Scanner(fis);
You should also revise your code for checking for numbers (I don't think you're checking for numbers anywhere).
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.