Reading Lines with BufferedReader - java

I am trying to read information from a file to interpret it. I want to read every line input. I just recently learned about bufferedreader. However, the problem with my code is that it skips every other line.
For example, when I put in 8 lines of data, it only prints 4 of them. The even ones.
Here is the code:
import java.io.*;
import java.util.Scanner;
public class ExamAnalysis
{
public static void main(String[] args) throws FileNotFoundException, IOException
{
int numOfQ = 10;
System.out.println();
System.out.println("Welcome to Exam Analysis. Let’s begin ...");
System.out.println();
System.out.println();
System.out.println("Please type the correct answers to the exam questions,");
System.out.print("one right after the other: ");
Scanner scan = new Scanner(System.in);
String answers = scan.nextLine();
System.out.println("What is the name of the file containing each student's");
System.out.print("responses to the " + numOfQ + " questions? ");
String f = scan.nextLine();
System.out.println();
BufferedReader in = new BufferedReader(new FileReader(new File(f)));
int numOfStudent= 0;
while ( in.readLine() != null )
{
numOfStudent++;
System.out.println("Student #" + numOfStudent+ "\'s responses: " + in.readLine());
}
System.out.println("We have reached “end of file!”");
System.out.println();
System.out.println("Thank you for the data on " + numOfStudent+ " students. Here is the analysis:");
}
}
}
I know this may be a bit of a bad writing style. I am just really new to coding. So if there is any way you can help me fix the style of the code and methods, I would be really thrilled.
The point of the program is to compare answers with the correct answer.
Thus I also have another question:
How can I compare strings with the Buffered Reader?
Like how can I compare ABCCED with ABBBDE to see that the first two match but the rest don't.
Thank you

the problem with my code is that it skips every other line
Your EOF check thows a line away on each iteration
while ( in.readLine() != null ) // read (first) line and ignore it
{
numOfStudent++;
System.out.println("Student #" + numOfStudent+ "\'s responses: " +
in.readLine()); // read (second) next line and print it
}
to read all line do the following:
String line = null;
while ( null != (line = in.readLine())) // read line and save it, also check for EOF
{
numOfStudent++;
System.out.println("Student #" + numOfStudent+ "\'s responses: " +
line); // print it
}
To compare Strings you need to use the String#compareTo(String other) method. Two Strings are equal if the return value is 0.

You don't compare Strings with readLine(). You compare them with String.equals().
Your reading code skips every odd line for the reason mentioned in the duplicate.

Related

How do I fix a NoSuchElementException from a input file?

I was wondering if anyone could help solve this NoSuchElements exception in my program which scans a text very large text and then is added to the ArrayList.
I have tried re-arranging the order of the code to see if that would fix it but now I don't know how to fix it.
Exception itself:
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1478)
at mainTest.main(mainTest.java:11)
mainTest class:
import java.io.*;
import java.util.*;
public class mainTest {
public static void main(String args[]) throws FileNotFoundException {
ArrayList<String> bigBoi = new ArrayList<>(500000);
Scanner scan1 = new Scanner(new File("LargeDataSet.txt"));
while (scan1.hasNextLine()) {
scan1.next();
String data = scan1.next() + " " + scan1.next();
bigBoi.add(data);
}
ArrayList<String> successful = new ArrayList<>(500000);
}
}
The unit of a .txt file :
https://drive.google.com/file/d/1MWfMKMhSvuopOt9WwquABgYBTt0M4eLA/view?usp=sharing
(sorry for needing you to download it from a google drive, the file is so long I probably would've been reported or something if I had pasted 500,000 lines)
Please check with scan1.hasNext() instead of scan1.hasNextLine():
while (scan1.hasNext()) {
scan1.next();
String data = scan1.next() + " " + scan1.next();
bigBoi.add(data);
}
There is an empty line at the end of LargeDataSet.txt which is valid for scan1.hasNextLine() check, but the scan1.next() throws NoSuchElementException as there's nothing to read.
Changing validation to scan1.hasNext() as suggested in the accepted answer, solves that problem, but the program could still crash if there are less than 3 entries on any line and accepts lines with more than 3 entries.
A better practice is to validate all externally supplied data:
while (scan1.hasNextLine()) {
String line = scan1.nextLine();
String[] tokens = line.split("\\s+"); //split by space(s)
if(tokens.length != 3) { //expect exactly 3 elements on each line
throw new IllegalArgumentException("Invalid line: " + line);
}
bigBoi.add(tokens[1] + " " + tokens[2]);
}

Writing to a java text file without overriding previous inputs and starting on a new line after ever complete entry

The idea behind this is to write to a text file with first name, last and a phone number and save it there. However when restarting the section of the program it will automatically start on a new line. Also facing a problem where for some reason the program keeps looping.
System.out.print("Enter First name: ");
Scanner FN = new Scanner(System.in);
String fn = FN.nextLine();
System.out.print("Enter Last name: ");
Scanner LN = new Scanner(System.in);
String ln = LN.nextLine();
System.out.print("Enter Number: ");
Scanner Num = new Scanner(System.in);
String num = LN.nextLine();
BufferedWriter writer = null;
FileWriter fWriter = new FileWriter("D:\\Second year\\OOP\\Coach1.txt", true);
try {
writer = new BufferedWriter(fWriter);
writer.write(fn + "||");
writer.write(ln + "||");
writer.write(num + "||");
writer.close();
} catch (Exception e) {
System.out.println("Error!");
}
Output:
FirstName|| Last name || number ||
rob || hel ||0774571829 ||
katie || bell || 09275664291 ||
inside try block change the line
writer.write(num + "||");
to
writer.write(num + "|| \n");
You need to make a simple addition at the end of last section printed for each entry. Change:
writer.write(num + "||");
to:
writer.write(num + "||\n");
\n is a new line character, it is used in Strings to indicate that this is a place you want to move to the next line with your String. When next time you try to write to this file, it will start from the new line.
If your intention is to have fixed width of your output Strings (in your example it's fixed, filled with white space characters to make it equal in each column), you need to use System.out.format() instead of System.out.println(). There are a few options how to use it, take a look at this Java tutorial (The format Method section, especially the part about width):
https://docs.oracle.com/javase/tutorial/essential/io/formatting.html
By the way, consider adding finally{} section to your try-catch block and move writer.close() to finally instead of keeping it in try block. It will provide closing writer even if exception occurs before reaching the end of try block.

Trouble using User Input and FileInputStream to create a file and read Integers from that file

I cannot explain my problem very well, this is the prompt.
I believe I am going in the right direction, my professor really went through this fast. Even though I am using the book and asking for help, it is to no avail.
'**Ask the user to enter a filename on the keyboard, including “.txt.” Read five integers from that file (all on the same line, separated by spaces) and tell the user their sum by printing it to the screen (console).**'
It compiles and runs, but when entering the filename(io.txt) I get an Exception in thread "main" java.util.NoSuchElementException: No line found
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String myString = " ";
Scanner inputStream = null;
System.out.println("Please enter a Filename, including '.txt' at the end: ");
myString = in.next();
try
{
inputStream = new Scanner(new FileInputStream(myString));
}
catch(FileNotFoundException e) //Giving the file not found a name,
{
System.out.println("Invalid File or filename");
System.out.println("Or could not be found,try again");
System.exit(0);
}
//True will always add on, not overwrite
int n1 = inputStream.nextInt();
int n2 = inputStream.nextInt();
int n3 = inputStream.nextInt();
int n4 = inputStream.nextInt();
int n5 = inputStream.nextInt();
String line = inputStream.nextLine(); //wait for new line, get the next line
inputStream.close( );
System.out.println("The five numbers read from the file are: ");
System.out.println(n1+" , "+ n2 + ", "+ n3 + ", "+ n4 +", "+ n5);
System.out.println("Which adds together to eqaul: " + (n1+n2+n3+n4+n5));
}
I want direction, not for someone to solve it for me.
After testing the code you gave it returns with
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at com.example.Test.main(Test.java:37)
which is the following line in your code
String line = inputStream.nextLine(); //wait for new line, get the next line
So your code tries to read another line from the file, but it can't find one. In reality what this means is your code is expecting to read
"1 2 3 4 5\n" from a file io.txt whereas the file actually contains "1 2 3 4 5" (no newline at the end of the file).
However since you've already read all the integers you needed you can simply stop there.
Also make sure to close your file stream.
Use in. nextLine() in place of in. next().

Coding with Java Eclipse

I need to make a program where a user can input a name, and the program will search through the file line by line until it has a match, then return all the match. So this is what i Have, I got the file into the program, but cant seem to code the program to search the file for the user input. Any help?
Assignment: this what the code has to be able to do.
read in each row, parse out the name part, perform a match on names, if match return full name, else move to next row. Have message if you reach the end without a match.
import java.util.Scanner;
import java.io.*;
public class USpres {
public static void main(String[] args) throws FileNotFoundException {
File file = new File ("USPres.txt");
Scanner kb = new Scanner(System.in);
Scanner scanner = new Scanner(file);
System.out.println("Please enter the name you would like to search for: ");
String name = kb.nextLine();
while (scanner.hasNextLine())
{
if(scanner.nextLine() == kb)
{
System.out.println("I found " +name+ " in file " +file.getName());
}
break;
if(scanner.nextLine() == kb)
{
System.out.println("I found " +name+ " in file " +file.getName());
}
should become
if(scanner.nextLine().equalsIgnoreCase(name))
{
System.out.println("I found " +name+ " in file " +file.getName());
}
just like they said above in the comments. Also, .equals() is meant to compare two Objects, not two strings. Since they are both strings, you may have success with this method, but I would suggest always using .equalsIgnoreCase() when comparing Strings.

Parsing txt file

I have to write a program that will parse baseball player info and hits,out,walk,ect from a txt file. For example the txt file may look something like this:
Sam Slugger,h,h,o,s,w,w,h,w,o,o,o,h,s
Jill Jenks,o,o,s,h,h,o,o
Will Jones,o,o,w,h,o,o,o,o,w,o,o
I know how to parse the file and can get that code running perfect. The only problem I am having is that we should only be printing the name for each player and 3 or their plays. For example:
Sam Slugger hit,hit,out
Jill Jenks out, out, sacrifice fly
Will Jones out, out, walk
I am not sure how to limit this and every time I try to cut it off at 3 I always get the first person working fine but it breaks the loop and doesn't do anything for all the other players.
This is what I have so far:
import java.util.Scanner;
import java.io.*;
public class ReadBaseBall{
public static void main(String args[]) throws IOException{
int count=0;
String playerData;
Scanner fileScan, urlScan;
String fileName = "C:\\Users\\Crust\\Documents\\java\\TeamStats.txt";
fileScan = new Scanner(new File(fileName));
while(fileScan.hasNext()){
playerData = fileScan.nextLine();
fileScan.useDelimiter(",");
//System.out.println("Name: " + playerData);
urlScan = new Scanner(playerData);
urlScan.useDelimiter(",");
for(urlScan.hasNext(); count<4; count++)
System.out.print(" " + urlScan.next() + ",");
System.out.println();
}
}
}
This prints out:
Sam Slugger, h, h, o,
but then the other players are voided out. I need help to get the other ones printing as well.
Here, try this one using FileReader
Assuming your file content format is like this
Sam Slugger,h,h,o,s,w,w,h,w,o,o,o,h,s
Jill Johns,h,h,o,s,w,w,h,w,o,o,o,h,s
with each player in the his/her own line then this can work for you
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(new File("file.txt")));
String line = "";
while ((line = reader.readLine()) != null) {
String[] values_per_line = line.split(",");
System.out.println("Name:" + values_per_line[0] + " "
+ values_per_line[1] + " " + values_per_line[2] + " "
+ values_per_line[3]);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
otherwise if they are lined all in like one line which would not make sense then modify this sample.
Sam Slugger,h,h,o,s,w,w,h,w,o,o,o,h,s| John Slugger,h,h,o,s,w,w,h,w,o,o,o,h,s
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(new File("file.txt")));
String line = "";
while ((line = reader.readLine()) != null) {
// token identifier is a space
String[] data = line.trim().split("|");
for (int i = 0; i < data.length; i++)
System.out.println("Name:" + data[0].split(",")[0] + " "
+ data[1].split(",")[1] + " "
+ data[2].split(",")[2] + " "
+ data[3].split(",")[3]);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
You need to reset your count car in the while loop:
while(fileScan.hasNext()){
count = 0;
...
}
First Problem
Change while(fileScan.hasNext())) to while(fileScan.hasNextLine()). Not a breaking problem but when using scanner you usually put sc.* right after a sc.has*.
Second Problem
Remove the line fileScan.useDelimiter(","). This line doesn't do anything in this case but replaces the default delimiter so the scanner no longer splits on whitespace. Which doesn't matter when using Scanner.nextLine, but can have some nasty side effects later on.
Third Problem
Change this line for(urlScan.hasNext(); count<4; count++) to while(urlScan.hasNext()). Honestly I'm surprised that line even compiled and if it did it only read the first 4 from the scanner.
If you want to limit the amount processed for each line you can replace it with
for( int count = 0; count < limit && urlScan.hasNext( ); count++ )
This will limit the amount read to limit while still handling lines that have less data than the limit.
Make sure that each of your data sets is separated by a line otherwise the output might not make much sense.
You shouldn't have multiple scanners on this - assuming the format you posted in your question you can use regular expressions to do this.
This demonstrates a regular expression to match a player and to use as a delimiter for the scanner. I fed the scanner in my example a string, but the technique is the same regardless of source.
int count = 0;
Pattern playerPattern = Pattern.compile("\\w+\\s\\w+(?:,\\w){1,3}");
Scanner fileScan = new Scanner("Sam Slugger,h,h,o,s,w,w,h,w,o,o,o,h,s Jill Jenks,o,o,s,h,h,o,o Will Jones,o,o,w,h,o,o,o,o,w,o,o");
fileScan.useDelimiter("(?<=,\\w)\\s");
while (fileScan.hasNext()){
String player = fileScan.next();
Matcher m = playerPattern.matcher(player);
if (m.find()) {
player = m.group(0);
} else {
throw new InputMismatchException("Players data not in expected format on string: " + player);
}
System.out.println(player);
count++;
}
System.out.printf("%d players found.", count);
Output:
Sam Slugger,h,h,o
Jill Jenks,o,o,s
Will Jones,o,o,w
The call to Scanner.delimiter() sets the delimiter to use for retrieving tokens. The regex (?<=,\\w)\\s:
(?< // positive lookbehind
,\w // literal comma, word character
)
\s // whitespace character
Which delimits the players by the space between their entries without matching anything but that space, and fails to match the space between the names.
The regular expression used to extract up to 3 plays per player is \\w+\\s\\w+(?:,\\w){1,3}:
\w+ // matches one to unlimited word characters
(?: // begin non-capturing group
,\w // literal comma, word character
){1,3} // match non-capturing group 1 - 3 times

Categories

Resources