New to Java. I'm having a hard time understanding why my code isn't running. I'm getting a InputMismatchException when I try to run my code.
I did some testing and problems occur if there's white space in my file such as "New York." I've been trying different things such as looping with .hasNextLine() instead of .hasnext() as suggested in other threads but to no avail. Sometimes I can get it to run until the end it gives me a NoSuchElementException. If you could please put me in the right direction, that would help a lot thank you!
import java.util.*;
import java.io.*;
public class StandaloneReport {
public static void main(String[] args) {
String fileInputName;
String fileOutputName;
String firstName;
String lastName;
String houseNumber;
String street;
String city;
String state;
String zip;
String productDescription;
double productPrice;
//Scanner obj1
Scanner input = null;
input = new Scanner(System.in);
System.out.printf("What is the file name?\n");
fileInputName = input.nextLine();
//Print out the name user inputed
System.out.println("File name is: " + fileInputName);
//Read the file
FileReader filereader;
Scanner readInput = null;
try {
readInput = new Scanner(filereader = new FileReader(fileInputName));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (readInput.hasNext())
{
firstName = readInput.next();
lastName = readInput.next();
houseNumber = readInput.next();
street = readInput.next();
city = readInput.nextLine();
state = readInput.next();
zip = readInput.next();
productDescription = readInput.nextLine();
productPrice = readInput.nextDouble();
Textfile looks like this:
Jane
Doe
10
Broadway
New York
NY
10001
Galaxy S10
199.99
2
Samsung Bluetooth
29.99
1
Slim Fit Hard Plastic Case
2.99
2
Charger
17.99
3
Error I get:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextDouble(Unknown Source)
at hey.bcs.hwk.purchases.standalonereport.StandaloneReport.main(StandaloneReport.java:55)
I expected it to read it smoothly so I can print it using PrintStream in another file but I cannot even get past this part.
To be honest your program is problematic in so many ways. But here's an explanation to fix the mismatch issue you mentioned.
readInput.nextLine()
will read the remainder of the current line. So after reading "Broadway" the Scanner stays in the same line and when you call nextLine, the Scanner yields whatever is left in the line for "Broadway", which is an empty String.
To avoid this situation, do
street = readInput.next();
readInput.nextLine();
To drop the current line("Broadway" for example). And then call
city = readInput.nextLine();
That way the program will read "New York" as you expected. As Tom mentioned in the comments, for more details, look at the question asked here.
Apart from the Scanner issue, your program is ambiguous as to where it ends – you did not provide closing brackets. That while loop seems redundant considering that your input is broken: it ceases to match what you have in your code after the "199.99" line. Please put your complete code on there and revise your sample input.
This is for one set of data, one data item per line. You have to make adjustments for multiple sets of data.
int i = 0;
while (readInput.hasNext())
{
if (i == 0)
{
firstName = readInput.nextLine();
}
else if (i == 1)
{
lastName = readInput.nextLine();
}
else if (i == 2)
{
houseNumber = readInput.nextLine();
}
else if (i == 3)
{
street = readInput.nextLine();
}
else if (i == 4)
{
city = readInput.nextLineLine();
}
else if (i == 5)
{
state = readInput.nextLine();
}
else if (i == 6)
{
zip = readInput.nextLine();
}
else if (i == 7)
{
productDescription = readInput.nextLine();
}
else if (i == 8)
{
productPrice = readInput.nextDouble();
}
i += 1;
} // End while
Related
I have a text file called UserDetails.txt that I am trying to read from.
Each line of the text file is as follows:
John : Doe : Seattle : jd3 : 1234
Jane : Doe : Olympia : jd4 : 5678
Jerry : Doe : Redmond : jd5 : 9101
And so on...
Each line has the first name, last name, username, and password of the registered user by which I am trying to search for only the last two variables (username and password).
public class LoginFrame extends javax.swing.JFrame
{
private static Scanner keyboard = new
Scanner(System.in);
String username;
String password;
String filePath = "UserDetails.txt";
public LoginFrame() {
initComponents();
}
private void jButtonLoginActionPerformed(java.awt.event.ActionEvent evt) {
username = jTextFieldUsername.getText();
password = jTextFieldPassword.getText();
verifyLogin(username,password,filePath);
}
public static void verifyLogin(String username,
String password, String filepath)
{
boolean match = false;
String tempUserName = "";
String tempPassword = "";
try
{
keyboard = new Scanner(new
File(filepath));
keyboard.useDelimiter("[:\n]");
while(keyboard.hasNext() && !match)
{
tempUserName = keyboard.next();
tempPassword = keyboard.next();
if(tempUserName.trim().equals(username.trim()) &&
tempPassword.trim().equals(password.trim()))
{
match = true;
}
}
keyboard.close();
System.out.print(match);
}
catch (Exception e)
{
System.out.print("Error");
}
}
This above code snippet is my original code by which I tried to use a delimiter to find the two specific values but it only seems to work if the username and password are the only two variables in the text file (with first and last names removed).
I've been reading up on the String.split() method so that I can replace my original use of the delimiter. However, I'm still struggling with how I can apply it to my text file. Many of the examples online explain how one can convert an individual line into a String array (which in my example, would have the username at index 3 and password at index 4). This is where I'm confused though. How can I implement the String.split() method without having to manually input it for every specific line? (since there are 50 users in the text file). Would it be possible to implement it with the Scanner.nextLine() method?
Here:
while(keyboard.hasNext() && !match)
{
tempUserName = keyboard.next();
tempPassword = keyboard.next();
You are reading each of the lines in pairs. You should instead call keyboard.next four times in each iteration. I am guessing that you intend to ignore the first name and last name, so you don't need to assign them to any variable:
while(keyboard.hasNext() && !match)
{
// These two lines read the first name and last name and do nothing with them
keyboard.next();
keyboard.next();
// these will read the username and password
tempUserName = keyboard.next();
tempPassword = keyboard.next();
If you want to use split, you need to call nextLine and hasNextLine instead:
while (keyboard.hasNextLine() && !match) {
String[] parts = keyboard.nextLine().split(" : ");
tempUserName = parts[2];
tempPassword = parts[3];
...
}
I've been trying to practice I/O file programming and I'm still at the basics. Writing into a file using the java was simple enough but reading to a file is beginning to give me a headache. Here's a simple program I tried to run(btw, I based the program from a book by Liang) .
import java.util.Scanner;
import java.io.File;
public class Reading {
private static Scanner n;
public static void main(String[] args) throws Exception
{
File files = new File("samples.txt");
n = new Scanner(files);
while(n.hasNext())
{
String firstName = n.next();
String mi = n.next();
String lastName = n.next();
int score = n.nextInt();
System.out.println(
firstName + " " + mi + " " + lastName + " " + score);
}
n.close();
}
}
Here's the error:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at OOPFinals.Reading.main(Reading.java:17)
How do I make this program work?
Help!
The NoSuchElementException is thrown by Scanner.next() and means there are no more tokens to be found in the file.
The problem here is that your while() loop only guarantees that there is at least ONE token left to read from the file, however on each iteration of the loop you are reading in FIVE tokens.
What is happening in your code, you are trying to read from the Scanner although there's nothing left there to read.
What you should do - You need to check n.hasNext() before each call to n.next() or n.nextInt(), or just read the entire line (which seems exactly what you want):
while (n.hasNextLine()) {
String line = n.nextLine();
System.out.println(line);
}
Your code is working given that the right input file "samples.txt" is provided. For example, given the following input:
Richard Phillips Feynman 100
Paul Adrien Dirac 90
Everything works fine, however if you use the following:
Richard Feynman 100
Paul Adrien Dirac 90
then you obtain the NoSuchElementException. In the last example, I removed the middle name that your program is expecting. As such, we can conclude that you are expecting to read information in a file with no information left to read. I recommend something like the following:
import java.util.Scanner;
import java.util.StringTokenizer;
import java.io.File;
public class Reading {
private static Scanner n;
public static void main(String[] args) throws Exception
{
File files = new File("samples.txt");
n = new Scanner(files);
String data;
while(n.hasNextLine() && !(data = n.nextLine()).equals(""))
{
StringTokenizer st = new StringTokenizer(data);
if(st.countTokens() >= 4) {
String firstName = (String) st.nextElement();
String mi = (String) st.nextElement();
String lastName = (String) st.nextElement();
int score = Integer.parseInt( (String) st.nextElement());
System.out.println(
firstName + " " + mi + " " + lastName + " " + score);
} else {
System.err.println("This line is malformed!");
}
}
n.close();
}
}
In this program, you can have a sample file that has empty lines and it expects to read 4 tokens per line or else it prints an error message informing you that a line has malformed input.
Sometimes when you're reading a file you'll run into various characters. Some are letters, some are numbers, and some are integers. You need to check whether it's a letter, number, or an integer because the following line assumes you are passing an integer:
int score = n.nextInt();
It can be resolved by checking for integers:
int score = 0;
if(n.hasNextInt()) { score = n.nextInt(); }
When you're reading from the program, make sure to take Cathial's answer into consideration. By using hasNext(), you're only checking if there is one string, also known as a token. You should check if there are n strings available where n is the number of .next() functions in your loop.
details:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine<Scanner.java:1540>
at CarReader2.main<CarReader2.java:30>
that's the entirety of the error.
My code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
public class CarReader2 {
String name, speed, acc;
public CarReader2(String carName, String carSpeed, String carAcc){
name = carName;
speed = carSpeed;
acc = carAcc;
}
public String toString(){
return "Name of car: " +name+ "\nSpeed of car: " +speed+"\nAcceleration of car: " +acc+"\n";
}
public static void main(String[] args) {
File file = new File("carlist.txt");
try {
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
String c1Name = sc.nextLine();
String c1Speed = sc.nextLine();
String c1Acc = sc.nextLine();
CarReader2 car1 = new CarReader2(c1Name,c1Speed,c1Acc);
car1.speed = c1Speed;
car1.acc = c1Acc;
String c2Name = sc.nextLine();
String c2Speed = sc.nextLine();
String c2Acc = sc.nextLine();
CarReader2 car2 = new CarReader2(c2Name,c1Speed,c1Acc);
car2.speed = c2Speed;
car2.acc = c2Acc;
System.out.println("Information on both cars");
System.out.println("First car:");
System.out.println(car1.toString());
System.out.println("Second car:");
System.out.println(car2.toString());
}
sc.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
It's supposed to read data of 2 cars from a file called carlist.txt, then print the data of both cars in the correct format.
carlist.txt is a text file containing:
jonathan 3 7
dio 8 2
And the program is supposed to print out,
Information on both cars
First car:
Name of car: jonathan
Speed of car: 3
Acceleration of car: 7
Second car:
Name of car: dio
Speed of car: 8
Acceleration of car: 2
The program compiles but doesn't run correctly and shows the error i posted at the very top.
You're using nextLine method wrong. Name, speed and acceleration are in the same line, but you're using 3 nextLine methods to read them. That's what happens when you try to read 6 lines from a file that only has 2 lines in it. use sc.next() instead of sc.nextLine().
You are reading too many lines. There are only two lines in your file, but you are trying to read 6. You can change your text file to:
jonathan
3
7
dio
8
2
or you can read one line and split out the information you want.
I am building a parser that recognizes simple commands such as "DOWN.", "UP." and "REP 3.". It must be able to parse the commands rather freely. It should be legal to write
"DOWN % asdf asdf asdf
."
Where % represents a comment and the fullstop signifying end-of-command. This fullstop can be on the next line.
This is all good and well so far, however I'm struggling with the Rep part (represents Repeat.)
I should be able to issue a command as follows:
DOWN .DOWN. REP 3 " DOWN. DOWN.
DOWN . % hello this is a comment
REP 2 " DOWN. ""
This should give me 17 DOWNS. The semantics is as follows for repeat: REP x " commands " where x is the amount of times it shall repeat the commands listed inside the quotation marks. Note that REP can be nested inside of REP. The following code is for handling the DOWN command. The incoming text is read from System.in or a text file.
public void repeat(String workingString) {
if (workingString.matches(tokens)) {
if (workingString.matches("REP")) {
repada();
} else
if (workingString.matches("(DOWN).*")) {
String job = workingString.substring(4);
job = job.trim();
if (job.equals("")) {
String temp= sc.next();
temp= temp.trim();
// Word after DOWN.
if (temp.matches("\\.")) {
leo.down()
// If word after DOWN is a comment %
} else if (temp.matches("%.*")) {
boolean t = comment();
} else {
throw SyntaxError();
}
} else if (job.matches("\\..*")) {
workingString += job;
System.out.println("Confirm DOWN with .");
}
} else if (workingString.matches("\\.")) {
instructions += workingString;
System.out.println("Fullstop");
} else if (workingString.matches("%.*")) {
comment();
} else {
// work = sc.next();
work = work.trim().toUpperCase();
System.out.println(work);
}
} else {
System.out.println("No such token: " + workingString);
}
}
I got a working start on the repeat function:
public String repada(){
String times = sc.next();
times.trim();
if (times.matches("%.*")) {
comment();
times = sc.next();
}
String quote = sc.next();
quote.trim();
if(quote.matches("%.*")){
comment();
quote = sc.next();
}
String repeater = "";
System.out.println("REP " + times + " "+quote);}
However I'm thinking my whole system of doing things might need a rework. Any advice on how I could more easily solve this issue would be greatly appreciated!
I am working on a homework assignment, and I am going a little "above and beyond" what is called for by the assignment. I am getting a run-time error in my code, and can not for the life of me figure out what it is that I have done wrong.
Here is the assignment:
Write a program that displays a simulated paycheck. The program should ask the user to enter the date, the payee’s name, and the amount of the check. It should then display a simulated check with the dollar amount spelled out.
Here is my code:
CheckWriter:
/* CheckWriter.java */
// Imported Dependencies
import java.util.InputMismatchException;
import java.util.Scanner;
public class CheckWriter {
public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
// Try to get the name
String name = "";
NameValidator validateName = new NameValidator();
while (validateName.validate(name) == false) {
System.out.println("Enter the name: ");
name = keyboard.nextLine();
if (validateName.validate(name) == false) {
System.out.println("Not a valid name.");
}
}
// Get the date
String date = "";
DateValidator validateDate = new DateValidator();
while (!validateDate.validate(date)) {
System.out.println("Enter the date (dd/mm/yyyy): ");
date = keyboard.nextLine();
if (!validateDate.validate(date)) {
System.out.println("Not a valid date.");
}
}
// Try to get the amount of the check
String checkAmount = "";
CurrencyValidator validateCurrency = new CurrencyValidator();
while (!validateCurrency.validate(checkAmount)) {
System.out.print("Enter the Check Amount (XX.XX): $");
checkAmount = keyboard.nextLine();
if (!validateCurrency.validate(checkAmount)) {
System.out.println("Not a valid check amount.");
}
}
String checkWords = checkToWords(checkAmount); // ERROR! (48)
System.out
.println("------------------------------------------------------\n"
+ "Date: "
+ date
+ "\n"
+ "Pay to the Order of: "
+ name
+ " $"
+ checkAmount
+ "\n"
+ checkWords
+ "\n"
+ "------------------------------------------------------\n");
}
private static String checkToWords(String checkAmount) {
/**
* Here I will use the string.split() method to separate out
* the integer and decimal portions of the checkAmount.
*/
String delimiter = "\\.\\$";
/* Remove any commas from checkAmount */
checkAmount.replace(",", "");
/* Split the checkAmount string into an array */
String[] splitAmount = checkAmount.split(delimiter);
/* Convert the integer portion of checkAmount to words */
NumberToWords intToWord = new NumberToWords();
long intPortion = Long.parseLong(splitAmount[0]); // ERROR! (84)
intToWord.convert(intPortion);
String intAmount = intToWord.getString() + " dollars";
/* Convert the decimal portion of checkAmount to words */
String decAmount = "";
long decPortion = Long.parseLong(splitAmount[1]);
if (decPortion != 0) {
NumberToWords decToWord = new NumberToWords();
decToWord.convert(Long.parseLong(splitAmount[1]));
decAmount = " and " + decToWord.getString() + " cents.";
}
return (intAmount + decAmount);
}
}
Note that I am using external class files to handle validation of the name, date, currency, and conversion from numbers to words. These class files all work as intended.
The error I am getting is:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at CheckWriter.checkToWords(CheckWriter.java:82)
at CheckWriter.main(CheckWriter.java:46)
I have commented the lines in my code that are causing the errors that I am experiencing.
Could someone please assist me in figuring where my code is going wrong? I can include the other class files if you feel that it would be needed.
EDIT: When I run the code, it asks for the name and date. Before asking for the check amount is when it throws the error.
EDIT 2: A huge thank you to cotton.m! Thanks to his advice, I have changed the while statements to look like this:
while(!validateDate.validate(date) && date == "")
This has now fixed my issue. It would appear that when validating data with a regex expression, an empty string will return true.
The String you are trying to parse in an empty length string.
My suggestion would be to
1) Check the value of checkAmount at the start of checkToWords - if it is blank there's your problem
2) Don't do that split. Just replace the $ like you did the , (I think this is your real problem)
Also you are going to have another issue in that 10000.00 is not a long. I see you are splitting out the . but is that really what you want?
It is NumberFormatException, the value in checkAmount (method parameter) is not a valid Number.
You need to set checkAmount=checkAmount.replace(",", "");
Otherwise checkAmount will still have , inside and causes NumberFormatExcpetion.
Your issue is with your delimiter regex, currently you are using \.\$ which will split on a literal . followed by a literal $. I'm assuming that what you are actually intending to do is to split on either a . or a $, so change your delimiter to one of the following:
String delimiter = "\\.|\\$"
or
String delimiter = "[\\.\\$]"
As your code is now, checkAmount.split(delimiter) is not actually successfully splitting the string anywhere, so Long.parseLong(splitAmount[0]) is equivalent to Long.parseLong(checkAmount).
It should be:
String delimiter = "[\\.\\$]";
and then you have to check that splitWord[i] is not empty.