Program compiles and runs perfectly until I try to execute my load method in main. Program crashes and gives me an input mismatch exception at
part number = scan.nextInt(); ..... Anyone know why?
public static InventoryManager load(String fileName) throws IOException,ClassNotFoundException
{
Scanner fileScan = new Scanner (new File(fileName));
Scanner stringScan;
InventoryManager StockChart = new InventoryManager();
// Part variables
String record = "";
int partNumber=0;
String description="";
int qty=0;
double cost = 0.00;
while(fileScan.hasNext())
{
record = fileScan.nextLine();
stringScan = new Scanner (record);
stringScan.useDelimiter(" "); //allows for separation when reading
partNumber = stringScan.nextInt(); // scans part number
description = stringScan.next(); // scans description
qty = stringScan.nextInt(); // scans the qty on hand
cost = stringScan.nextDouble(); // scans the item cost
//create new part object for each line in file
StockChart.addStock(new Stock(partNumber,description, qty,cost));
}
return StockChart; // return new list back to InventoryClerk program
}
Text File is formatted as follows (disregard spaces in between):
1117[tab]1/2-13 FHN[tab]450[tab]6.11
1118[tab]1/2-13 FHN[tab]100[tab]0.23
1119[tab]1/2-13 FHN[tab]100[tab]4.11
A better way rather than using the stringScan Scanner object is to simply to use String.split on the record String
e.g.
while(fileScan.hasNext())
{
record = fileScan.nextLine();
String el[] = record.split (" ");
partNumber = Integer.parseInt (el[0]);
description = el[1];
// etc
Related
Even though the file Movie_db.txt isn't empty, I get the following exception:
the text file consists of this:
hank horror 20.0 18 1
public void syncDB(List<Movie> movieList) throws IOException {
Scanner scanner = new Scanner("Movie_db.txt");
BufferedReader reader = null;
try {
String line = null;
String title;
String genre;
double movieDuration;
int ageRestriction;
int id;
while (scanner.hasNext()) {
title = scanner.next();
genre = scanner.next();
movieDuration = scanner.nextDouble();
ageRestriction = scanner.nextInt();
id = scanner.nextInt();
movieList.add(new Movie(title, genre, movieDuration, ageRestriction, id));
}
} catch (Exception e) {
System.out.println("List is empty");
}
}
Considering your path is correct, there is a problem in your code. I'd change this line
Scanner scan = new Scanner("Movie_db.txt");
with this one
Scanner scan = new Scanner(Paths.get("Movie_db.txt"));
The reason is that in your snippet the Scanner only reads the string "Movie_db.txt" and in the second snippet it recognizes as the path to file.
Read Scanner documentation for more info
genre = scan.next(); line is throwing exception because nothing is left to read from file now, which causes catch block to execute.
You are providing a string to Scanner which is a valid input for scanner. Hence, it never reads the file.
Scanner scan = new Scanner(new File("full_path_to_container_dir/Movie_db.txt"));
Please have a look at this blog on how to read from a file using scanner - https://www.java67.com/2012/11/how-to-read-file-in-java-using-scanner-example.html.
I have a program which reads some data under a file reader and then creates an instance of another class which models the data. Anyway that class works (has been tested with some hard coded values) but I now want to output the data of the instance of a Patient being read under the file reader but seem unable to.
Could anyone tell me where i'm going wrong.
You are not adding Patient instances to newPatient collection, that's why it's empty and you are not getting anything printed out. Add elements to queue:
while(scan.hasNextLine()){
String firstname = scan.nextLine();
String surname = scan.nextLine();
String illness = scan.nextLine();
int illnessSeverity = scan.nextInt();
String newLine = scan.nextLine();
newPatient.add(new Patient(firstname,surname,illness,illnessSeverity));
for (Patient newPatientData : newPatient) {
System.out.println(newPatientData);
}
You need to add data first to the Priority Queue. I think you missed that .
PriorityQueue<Patient> newPatient = new PriorityQueue<>();
File fileName = new File("patients.txt");
Scanner scan = null;
try {
scan = new Scanner(fileName);
while(scan.hasNextLine()){
String firstname = scan.nextLine();
String surname = scan.nextLine();
String illness = scan.nextLine();
int illnessSeverity = scan.nextInt();
String newLine = scan.nextLine();
Patient newP = new Patient(firstname,surname,illness,illnessSeverity);
newPatient.add(newP);
}
for (Patient newPatientData : newPatient) {
System.out.println(newPatientData);
}
} catch(Exception e) {
System.out.println("ERROR - file not found");
}
I have a class which reads a file and takes in a user input with a scanner and if the scanner equals a part of a line in that file, it will display a string from the same line.
How would I go and create a Junit test method for this?
Here is some of my code that I want a test method for:
Scanner Input = new Scanner(System.in);
String name = Input.nextLine();
BufferedReader br;
try{
br = new BufferedReader(new FileReader(new File(filename)));
String nextLine;
while ((nextLine = br.readLine()) != null)
{
if (nextLine.startsWith("||"))
{
int f1 = nextLine.indexOf("*");
int f2 = nextLine.indexOf("_");
fName = nextLine.substring(f1+1, f2);
if (name.equals(fname))
{
String[] s1 = nextLine.split("_");
String sName = s1[1];
System.out.println(sName);
}
}
}
my data file looks like this
||
*Jack_Davis
*Sophia_Harrolds
I have tried to use this code in my test method
#Test
public void testgetSurname() {
System.out.println("get surname");
String filename = "";
String expResult = "";
String result = fileReader.getSurname(filename);
assertEquals(expResult, result);
filename = "datafiles/names.txt";
String data = "Jack";
InputStream stdin = System.in;
try{
System.setIn(new ByteArrayInputStream(data.getBytes()));
Scanner scanner = new Scanner(System.in);
System.out.println(scanner.nextLine());
} finally {
System.setIn(stdin);
expResult = "Davis";
}
String result = fileReader.getSurname(filename);
assertEquals(expResult, result);
}
try this for example:
You could enhance it by simulate the console automatically (see below)
#Test
public void test_scan() throws Exception
{
Myclass myobject=new myobject(); // with args
myobject.load(filename); // you must definie the filename
String result=myobject.scaninput_and_compare(); // you must use scan in, and compare
if (!result.equals(what_I_am_expecting) throw new Exception("EXCEPTION scaninput_and_compare");
// If you arrive here, it's OK
}
If you want to automatize the console input, use that:
Courtesy of: JUnit: How to simulate System.in testing?
String data = "What_I_could_put_in_console";
InputStream stdin = System.in;
System.setIn(new ByteArrayInputStream(data.getBytes()));
Scanner scanner = new Scanner(System.in);
System.setIn(stdin);
Beware of catch Exception inside, to finish with a "good" System.in It's ok for a test alone, for several, you should verify.
With your code:
public String scaninput_and_compare(String filename)
{
Scanner Input = new Scanner(System.in);
String name = Input.nextLine();
BufferedReader br;
try{
br = new BufferedReader(new FileReader(new File(filename)));
String nextLine;
while ((nextLine = br.readLine()) != null)
{
if (nextLine.startsWith("||"))
{
int f1 = nextLine.indexOf("*");
int f2 = nextLine.indexOf("_");
fName = nextLine.substring(f1+1, f2);
if (name.equals(fname))
{
String[] s1 = nextLine.split("_");
String sName = s1[1];
return sName;
}
}
}
// NO GOOD
return "lose";
}
#Test
public void test_scan() throws Exception
{
Myclass myobject=new myobject(); // with args
String filename="good_filename";
// MOCK System.in
String data = "Jack";
InputStream stdin = System.in;
System.setIn(new ByteArrayInputStream(data.getBytes()));
String result=myobject.scaninput_and_compare(filename); // you must use scan in, and compare
// RESTABLISH System.in
Scanner scanner = new Scanner(System.in);
System.setIn(stdin);
if (!result.equals("Davis") throw new Exception("EXCEPTION scaninput_and_compare");
// If you arrive here, it's OK
}
BETTER design, and testing more easy: separate your scanner of System.in, from your file parsing. Just do a function with (filename, fname), and it will be direct to test :
assertEquals(myobject.scaninput_and_compare(filename,"Jack"), "Davis");
One way to do it:
Step 1
Refactor your code, so that Scanner is one of the parameters passed into your method.
Step 2
For your test, use constructor Scanner(File file) or Scanner(String source) to feed "what would the user type" - while in the real world (from your main() you'd create Scanner(System.in)
or
Refactor your code to get a protected Scanner getScanner() { } and then use a Mocking framework (I like Mockito) to mock that method and return your String-prepped Scanner (see Step 2)
Requested example (the refactoring)
/**
* Reads the next line from the Scanner
*/
protected String getNextLine(Scanner scanner) {
//You know how to do that.
}
/**
* Check if file contains that name and return matching line.
* Throws NameNotFoundException (you'd need to create) if not found.
*
* If it were my code, i'd refactor even more and pass in List<String>
* here with the lines from the file
*/
public String matchSurname(String name, File dataFile) throws NameNotFoundException {
//Iterate over file...
if(isMatchingSurname(name, line)) {
return line;
}
// end iteration
//Still here? Throw Exception!
throw new NameNotFoundException();
}
/**
* Checks if given Name matches the read line
*/
public boolean isMatchingSurname(String name, String lineFromFile) {
//All the checks
}
Now you've broken your problem down in nice small bites. Unit testing would now be for individual methods only - so one for testing reading a line from Scanner, one for testing the Matching logic and one for correct file iteration.
I am not sure why I am receiving this error and what's the fix to it in the following snippet of code:
String srcFile=args[0];
Scanner fileIn = new Scanner(srcFile);
// if (fileIn.isFile() && fileIn.canRead())
CarDB carDatabase = new CarDB();
while(fileIn.hasNext())
{
String[] line = fileIn.nextLine().split(",");
double mpg = Double.parseDouble(line[0]);
int cylinders = Integer.parseInt(line[1]);
int power = Integer.parseInt(line[2]);
int year = Integer.parseInt(line[3]);
int region = Integer.parseInt(line[4]);
String makerName = line[5].trim();
String carName = line[6].trim();
carDatabase.addCar(makerName, carName, mpg, cylinders, power, year, region);// add car
carDatabase.addMaker(makerName);//add maker to list
}
and line 36 is : double mpg = Double.parseDouble(line[0]);
Error is:
java CarDBMain cars.txt
java.lang.NumberFormatException: For input string: "cars.txt"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1250)
at java.lang.Double.parseDouble(Double.java:540)
at CarDBMain.main(CarDBMain.java:36)
You are having this Scanner fileIn = new Scanner("cars.txt"); so your first line will be "cars.txt"
Scanner fileIn = new Scanner(new File(srcFile));//Or probably path of file
Here create file and pass the commandline argument,means file path,to File constructor and pass that file to Scanner.
You are passing file name as String to Scanner.
Constructors
Scanner(File source)<---Takes File you want to read
Scanner(String source)<----Takes String you want to read
etc.
I was trying to take the input of the filename from the user and then proceed to doing all the calculations. but it keeps returning me an error. the file exists in the same directory.
import java.io.*;
import java.util.*;
public class test{
public static void main(String args[]) throws FileNotFoundException {
//File fin = new File ("matrix1.txt");
Scanner scanner = new Scanner(System.in);
scanner.nextLine(); // removes the first line in the input file
String rowLine = scanner.nextLine();
String[] arr = rowLine.split("=");
int rows = Integer.parseInt(arr[1].trim());
String colLine = scanner.nextLine();
String[] arr2 = colLine.split("=");
int cols = Integer.parseInt(arr2[1].trim());
double [][]matrix = new double [rows][cols];
for (int i=0; i<rows;i++){
for (int j=0; j<cols;j++) {
matrix[i][j]= scanner.nextDouble();
}
}
System.out.println(rows);
System.out.println(cols);
for (int i=0; i<rows; i++)
{ for (int j=0;j<cols;j++) {
System.out.println(matrix[i][j]);
}
}
}
}
There is one issue with the code. The scanner will just give you the name of the file as string from command line. So, you need to first get the command line argument and then create one more scanner using the constructor which takes file object. e.g.
Scanner scanner = new Scanner(System.in);
Scanner fileScanner = new Scanner(new File(scanner.nextLine()));
String rowLine = fileScanner.nextLine();
System.out.println(rowLine);
String[] arr = rowLine.split("=");
int rows = Integer.parseInt(arr[1].trim())
You realize that you are only using a Scanner of type System.in, right? This means that you aren't even looking at a file, you are looking at user input only. This is regardless of whether you have the first line commented out or not. To use a file, you could use a FileInputStream or a couple other File handling classes.
FileInputStream fs = new FileInputStream(new File("matrix1.txt"));
//do stuff with the stream
Heres the java docs for FileInputStream: http://download.oracle.com/javase/1.4.2/docs/api/java/io/FileInputStream.html
Edit: After seeing your comment on what the actual error was, I realize there are more problems with the code than just the way you are handling input. Your error is almost certainly happening at one of the first 2 array accessors, the arr1.trim() calls. That means the user input has nothing on the right side of the "=" sign, or there is no "=" sign in the user input.