Why do I get a "No line found" Exception in this code? - java

The following method causes a No line found Exception:
private static String getRebaseAnswer(boolean isFirst, boolean isLast) {
System.out.println("Would you like to (c)ontinue, (s)kip this commit, or"
+ " change this commit's (m)essage?");
Scanner in = new Scanner(System.in);
String answer;
while (true) {
answer = in.nextLine(); // <--- This Line
if (answer.equals("c") || answer.equals("m")) {
in.close();
return answer;
} else if (answer.equals("s") && !isFirst && !isLast) {
in.close();
return answer;
} else {
System.out.println("Would you like to (c)ontinue, (s)kip this commit, or"
+ " change this commit's (m)essage?");
}
}
}
I am calling the method in this method:
...
String answer;
Scanner in;
currHead = branchHeads.get(arg);
while (toRebase != null) {
System.out.println("Currently replaying:");
toRebase.getNode().printInfo();
answer = getRebaseAnswer(isFirst, toRebase.getParent() == null); // <--- This Line
...
What is causing the error?? Shouldn't the scanner wait for me to input a line before continuing the getRebaseAnswer method? A different method in my code has the exact same structure as the above method and encounters no problems. I've checked multiple other posts about this problem but their suggestions are all not pertinent to this problem or do not solve it.
This method runs with no problems:
private static boolean handleDangerous() {
System.out.println("Warning: The command you entered may alter the files in your"
+ " working directory. Uncommitted changes may be lost. Are you sure you"
+ " want to continue? (yes/no)");
Scanner in = new Scanner(System.in);
String answer;
while (true) {
answer = in.nextLine();
if (answer.equals("yes")) {
in.close();
return true;
} else if (answer.equals("no")) {
in.close();
return false;
} else {
System.out.println("Not a valid answer, please enter (yes/no).");
}
}
}

When you create a scanner connected to System.in and close it, you also close System.in. Therefore, subsequent attempts to read from System.in will result in the exception you observe.
The way is avoid this is to create the Scanner only once, and never close it until your program is finished. This Scanner should be passed to whichever function needs to read from System.in.

don't close scanner otherwise Stream will also be closed.
in.close();
remove this line from current location and put it in main method at the end so after all the operation stream will be closed..
You might be calling some other method which have already closed the stream and then you are calling this method.

Related

I keep getting an FileNotFoundException error, but I declared it thrown in the method and included a try/catch block

I can make this code work if I modify the main method class, but I am supposed to make it work WITHOUT modifying it at all. I'm confused as to what is causing the error.
Here is the method I have written in a class
public boolean addSongs(String fileName)throws FileNotFoundException
{
Scanner scan = null;
try //open the try block for FNFE
{
//open the file, declare scanner, set endFile to false
scan = new Scanner(new File(fileName));
boolean endFile = false;
while(!endFile) //continues until the end of the file
{
try //try block for mismatch exception or no such element
{
//scan in line and read through it with new delimiter
String line = scan.nextLine();
Scanner read = new Scanner(line);
read.useDelimiter("/");
//scan in name, minutes, and seconds on the scanned line
String scannedName = read.next();
int scannedMin = read.nextInt();
int scannedSec = read.nextInt();
//print the results
System.out.print("Name: " + scannedName + "\n" +
"Minutes: " + scannedMin + "\n" +
"Seconds: " + scannedSec +
"\n-----------------------------------\n");
//add to the playlist if no errors
title.add(new Song(scannedName, scannedMin, scannedSec));
}
catch(InputMismatchException e) // handle when data is N/A
{
String error = scan.nextLine(); //consume the error and return to see where error is occurring
System.out.print( " ERROR (cause): " + error + "\n");
}
catch(NoSuchElementException e) // handle when no more data in file
{
endFile = true; //nothing in file set endFile
}
} //close try block
//close and return true
scan.close();
return true;
}// close loop
//return false if no file found
catch (FileNotFoundException e)
{
System.out.println("THERE IS NO FILE BRETHREN");
return false;
}
}// close method
Here is the code thats causing an issue in the main class
if (b.addSongs("revolver.txt"))
System.out.println("Songs in file revolver.txt added successfully");
System.out.printf("The playlist \"%s\" has a total playing time of %5.2f minutes\n", b.getName(), b.getPlayingTime());
System.out.printf("It includes the song \"%s\" with a playing time of %4.2f minutes\n", song, b.getPlayingTime(song));
System.out.printf("The longest song is \"%s\"\n", b.longestSong());
if (b.removeSong("Taxman"))
System.out.println("The song \"Taxman\" was removed successfully");
System.out.println("\n" + b); }
This is the error message:
PLTest.java:32: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
b.addSongs("revolver.txt");
^
My solution is to add in a FileNotFoundException throw in the main class, but as I stated before ._. I am banned from changing it. I don't see what keeps going wrong since the invoked method throws the exception. It's the only error that occurs and when I add the throw to the main class everything works perfectly.
For a side note: I attempted to put the throw in another method and got a duplicate error that went away when I just removed the throw. I don't know if that is relevant but my next guess is to find a way to change the boolean values without a try/catch?
Use
scan = new Scanner(new FileReader(new File(fileName)));
instead of
scan = new Scanner(new File(fileName));
and make sure that the text files are along side of the src folder. Hove the exceptions will solved.

Catch exceptions in a do-while loop?

Can someone explain and help me fix this program.
import java.util.*;
import java.io.*;
public class test {
public static void main(String[] args) {
Scanner key = new Scanner(System.in);
boolean clear;
int in = 0;
do {
clear = true;
try {
in = key.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid");
clear = false;
}
} while (clear == false);
String stringIn = Integer.toString(in);
String[] dec = stringIn.split("");
for (int i = 1; i < (dec.length); i++) {
System.out.print(dec[i] + " ");
}
}
}
Whenever I enter a invalid input instead of an int, my program keeps looping "Invalid" instead of giving the option to enter a new value for in.
The problem is that if the scanner fails to find an input in the correct format, it will throw an exception and not read the input.
Because the scanner does not read the invalid int input, the next time nextInt is called, it will try to read the invalid input again, and miserably fails at it, printing another "invalid!"
So you need to read the input afterwards if it finds an invalid int:
// do this in the catch block:
key.next();
This makes sure that the next token is read.
Full code:
Scanner key = new Scanner(System.in);
boolean clear;
int in = 0;
do {
clear = true;
try {
in = key.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid");
clear = false;
key.next();
}
} while (clear == false);
String stringIn = Integer.toString(in);
String[] dec = stringIn.split("");
for (int i = 1; i < (dec.length); i++) {
System.out.print(dec[i] + " ");
}
Check the API of the nextInt method:
This method will throw InputMismatchException if the next token cannot be translated into a valid int value as described below. If the translation is successful, the scanner advances past the input that matched.
Meaning, that if it's not successful - it will not advance and will try to execute nextInt over the illegal token over and over again failing every time.
Try adding next() into the exception catch clause, it should skip the token and read the next one then. next() reads a String, so it does not really care about the formatting, and will allow you to advance the position in the stream to read the next token.
The problem is that you are writing to the console inside the catch, so then when you call key.nextInt() in the try the program reads the value you print to the console, so an easy way to solve this is to add a line like: key.nextLine() inside the catch and that will solve your problem.

How to correctly use try-catch-finally blocks in Java?

What would be the proper way to use the finally block to close out of the file that I was in : event.dat. If you could help me makes sense of this, I'd greatly appreciate it. I've literally spent 4 hours moving things around, playing with the code and searching for answers online, but to no avail. Code works great without that portion, but I need to know how it works for future instances. Thank you and have a good day!
I am having issues with this block:
finally{
fstream.close();
}
Which is located in the following code:
String answer;
String letter;
String inType = "";
double inAmount = 0;
double amount;
description();
GironEventClass newInput = new GironEventClass();
try{
File infile = new File("event.dat");
Scanner fstream = new Scanner(infile);
System.out.println("File Contents ");
while(fstream.hasNext())
{
inAmount = fstream.nextInt();
inType = fstream.next();
try{
newInput.donations(inType, inAmount);
}
catch(IllegalArgumentException a){
System.out.println("Just caught an illegal argument exception. ");
}
finally{
fstream.close();
}
}
System.out.println("Total Sales: " + newInput.getSale());
System.out.println("Donations: " + newInput.getDonated());
System.out.println("Expenses: " + newInput.getExpenses());
}
catch (FileNotFoundException e){
System.out.println("\nEvent.dat could not be opened. ");
}
do{
System.out.print("Are there any more items to add that were not in the text file? (Type 'Y' or 'N')");
answer = keyboard.next();
if (("Y".equals(answer)) || ("y".equals(answer)))
{
letter = inLetter();
amount = inAmount();
newInput.donations(letter, amount);
}
}while (("Y".equals(answer)) || ("y".equals(answer)));
newInput.display();
}
public static String inLetter(){
Scanner keyboard = new Scanner(System.in);
String result;
String resultTwo;
System.out.println("T = Tiket Sales");
System.out.println("D = Donations");
System.out.println("E = Expenses");
System.out.print("Please input an identifier ");
result = keyboard.nextLine();
resultTwo = result.toUpperCase();
return resultTwo;
}
public static double inAmount(){
Scanner keyboard = new Scanner(System.in);
double result;
System.out.println("Please input an amount ");
result = keyboard.nextInt();
if(result <= 0.0){
System.out.print("Please input a positive and non-zero amount ");
result = keyboard.nextInt();
}
return result;
}
public static void description(){
System.out.println("The program will ask you what amount is being spent on what.");
System.out.println(" ex: expenses, ticket sales, and profts.");
System.out.println("This program will help determine whether the event generated or lost money.");
}
This is how the scanner should work:
while scanner has object
read them ( one object per method's call)
when objects are done
close the reader.
Your problem is that you use the close function when the while conclusion is true. So you should put it outside of the while loop
The Try block attempts to do something.
The Catch block only executes if something went wrong during the Try block.
The Finally block executes after the Try block (and Catch block, if executed) EVERY time.
Your issue is that you attempt to close the fstream inside the while loop.
while(fstream.hasNext()) <----- referencing fstream
{
inAmount = fstream.nextInt();
inType = fstream.next();
try{
newInput.donations(inType, inAmount);
}
catch(IllegalArgumentException a){
System.out.println("Just caught an illegal argument exception. ");
}
finally{
fstream.close(); <---- closing said stream
}
}
Since you've closed the stream, this while loop should only ever execute once. That being said, close the fstream outside the while loop and your program should return to normal.
You can also move the while loop inside the try block, which would work as well.
You need to declare fstream outside the try block otherwise it will be not visible in the finally block.
File infile = null;
File infile = null;
try {
infile = new File("event.dat");
fstream = new Scanner(infile);
...
} catch ( ) {
...
} finally {
// You need to handle exceptions also here
infile.close();
fstream.close();
}
You can also use the new try with resources syntax and leave to the jvm the closure of your streams.

Java bufferreader crashes on ctrl z

I'm making a game which plays until the user enters quit in the command line.
The user can enter different commands like get and go, with the get command the user can say what to get like, get baseball bat. What I do in my code is split the command.
everything is working fine but I have found a bug which I can't solve. If I enter "get" and press space and then ctrl+z it gets in a while loop which never ends.
It only happens with ctrl+z (1 time with ctrl c but after that 1 time not anymore)
private void run()
{
while (! quitCommand)
{
String input = null;
try
{
input = null;
System.out.println("Input "+ input);
System.out.println("Give a command.");
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
input = is.readLine();
handleCommand(input);
// As long as the command isn’t to quit:
// get the next input line and handle it. (With handleCommand.)
}
catch (Exception e)
{
System.out.println("Something went wrong we are sorry try again.");
e.printStackTrace();
}
}
}
/**
* #param userInput (This is the entire input string from the user.)
*
* (Tell others to) Perform the task which belongs to the given
* command.
*/
private void handleCommand(String userInput)
{
// Split the user input string.
if (userInput != null) // user input can not be empty
{
String[] delenTekst = userInput.split(" ");
// The first word is a command. The rest is extra information
String command = delenTekst[0];
String extra = "";
for (int i = 1; i < delenTekst.length; i ++)
{
if (i == 1)
{
extra = extra + delenTekst[i];
}
else
{
extra = extra +" " + delenTekst[i];
}
}
switch (command)
{
// Check if the command is to travel between rooms. If so, handle
case "go"
:
this.checkRoomTravel(extra);
break;
// If there isn't any room travel, then check all other command
case "get"
:
System.out.println("Looking for " +extra );
this.handleGetCommand(extra);
break;
case "quit"
:
quitCommand = true;
break;
default
:
System.out.println("Command is not known try help for information");
break;
}
}
else
{
userInput = "help";
}
}
I'm new to java so it can be something really simple.
On the top of my script I have a private boolean quitCommand = false; which is to check if the user entered quit.
Ctrl+Z closes the Console and therefore your readLine() returns null as pretended to indicate that end of file was reached. So all you need to do, is to check for null returned by readLine() and handle this as you handle the "quit".
I've changed your code (just to test my thesis) and also stream lined a few things, e.g. you dont need to recreate a BufferedReader every time you read a line.
private boolean quitCommand = false;
private void runIt() {
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
String input = null;
while(!quitCommand) {
try {
System.out.print("Give a command: ");
input = is.readLine();
// As long as the command isn’t to quit:
if(input == null || "quit".equals(input.trim())) quitCommand = true;
if(quitCommand) break;
// get the next input line and handle it. (With handleCommand.)
String[] words = input.trim().split("\\s+");
// ** This is the original handleCommand line **
System.out.println(input + ":" + Arrays.toString(words));
}
catch (Exception e) {
System.out.println("Something went wrong we are sorry try again.");
e.printStackTrace();
}
}
}
BTW: To split the input into words I'd use the regular expression as shown in my code. This works also if the user enters tabs or multiple spaces.
On DOS/Windows Ctrl+Z means end of input. This causes readLine() to return null no matter how many times you call it. This is likely to cause your code to fail as you don't appear to check for it. I suspect you are getting a NullPointerException which you are pretending didn't happen and trying again, endlessly.

Password masking does not terminate the program when needed

I developed the following application in which I needed to masking the PIN and terminate the program after the user has entered the wrong PIN thrice. However, the program terminates only if i close the stopThread at the beginning (I commented it in the code below), however the password masking does not occur for all the three channces when I do so. But, when I close the stopThread just before displaying the login successful screen, the program does not terminate. I need to use ctrl+c to end the program.
Any help is greatly appreciated.
boolean stopThread = false;
boolean hideInput = false;
boolean shortMomentGone = false;
public static double userBal=0.0D;
public void run(){
try{
sleep(500);
} catch(InterruptedException e){
}
shortMomentGone = true;
while(!stopThread){
if(hideInput){
System.out.print("\b*");
}
try{
sleep(1);
} catch(InterruptedException e){
}
}
}
public static final int NB_OF_TRIES = 3;
public void validatePin(){
BankAccount getAll=new BankAccount();
String pin="";
getAll.Login();
Login hideThread =new Login();
hideThread.start();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try{
do{
} while(hideThread.shortMomentGone == false );
// Now the hide thread should begin to overwrite any input with "*"
hideThread.hideInput = true; // Read the PIN
System.out.println("\nPIN:");
boolean pinMatch = false;
int i = 0;
while(!pinMatch && i < NB_OF_TRIES) {
hideThread.hideInput = true;
pin = in.readLine();
i++;
//hideThread.stopThread = true; //Program terminates after third attempt
//PIN masking is stopped, if uncommented
System.out.print("\b \b");
if(pin.equals(" ")){
System.out.println("Please do not leave unnecessary spaces!");
getAll.Login();
}else if(pin.equals("")){
System.out.println("Please do not press the enter key without entering the PIN!");
getAll.Login();
}
FileInputStream fileinputstream = new FileInputStream(".\\AccountInfo.txt");
DataInputStream datainputstream = new DataInputStream(fileinputstream);
BufferedReader bufferedreader1 = new BufferedReader(new InputStreamReader(datainputstream));
do
{
String s1;
if((s1 = bufferedreader1.readLine()) == null)
{
break;
}
if(s1.trim().charAt(0) != '#')
{
String as[] = s1.split(" ");
if(pin.equals(as[0]))
{
System.out.println("You have login!");
String s2 = as[2];
userBal = Double.parseDouble(s2);
getAll.balance = userBal;
hideThread.stopThread = true;
getAll.MainMenu();
System.exit(0);
}else if(pin != as[0]){
System.out.println("Invalid PIN!");
getAll.Login();
System.out.println("\n NOTE :- You are only allowed to enter the PIN THREE times. The number of tries remaining before your card is blacklisted are "+i + "\n Please re-enter your PIN");
}
}
} while(true);
datainputstream.close();
}//End of While Loop
}catch(Exception exception)
{
System.err.println((new StringBuilder()).append("Error: ").append(exception.getMessage()).toString());
}//End of try-catch block
}
There's a readPassword() method in java.io.Console, use that. Why do you need a separate thread at all? That makes everything way too complicated.
Regarding your question why this does not close: Java may optimize while(isTrue){} to something like if(isTrue) { while(true) { } } if you don't set isTrue volatile or synchronize the access to isTrue (getter/setter). This optimizations is called hoisting and explained in Effective Java SE, item 66.
Here is an article which explains exactly your problem: echoing * instead of blanks.
http://java.sun.com/developer/technicalArticles/Security/pwordmask/
They are going the complicated way, too but it works. I would prefer blanks over asterisks since that is the easier way to go. Not echoing * is *nix standard afaik.
Actually after I analysed it a but more i realized that the reason the system wont terminate is because it is not kept in the proper place. Therefore, the solution would be to end the program as soon as the while loop is closed and then everything would work fine.
} while(true);
datainputstream.close();
}//End of While Loop
System.exit(0); // After the system is closed the program would terminate after the third attempt
}catch(Exception exception)
{
System.err.println((new StringBuilder()).append("Error: ").append(exception.getMessage()).toString());
}//End of try-catch block

Categories

Resources