Java NoSuchElementException for Scanner in while loop [duplicate] - java

This question already has an answer here:
How to use java.util.Scanner to correctly read user input from System.in and act on it?
(1 answer)
Closed 7 years ago.
EDIT: While this issue has been marked as a duplicate, the other issue is different to my situation; it seems as though the program is ignoring this line:
decision = scan.nextInt();
I'm having some trouble with my scanner. I have a program that runs off a simple menu system.
The program works, but whenever it goes back to repeating the program again (I made the program have the ability to repeat by putting it in a while loop) it throws this error:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:919)
at java.util.Scanner.next(Scanner.java:1542)
at java.util.Scanner.nextInt(Scanner.java:2172)
at java.util.Scanner.nextInt(Scanner.java:2131)
at GuardSearch.Menu(GuardSearch.java:29)
at GuardSearch.main(GuardSearch.java:8)
The program all works on the first run through the menu and its actions, but then when the call of the if statement is completed and the program returns to the while loop, it throws this exception. What am I missing?
I can post all the classes of the program if needed, however I believe my problem is within the following class:
import java.util.Scanner;
import java.lang.*;
public class GuardSearch {
public static void main(String[] args) {
Menu();
}
public static void Menu(){
Scanner scan = new Scanner(System.in);
boolean leave = false;
while(leave!=true){
final String ANSI_CLS = "\u001b[2J";
final String ANSI_HOME = "\u001b[H";
System.out.print(ANSI_CLS + ANSI_HOME);
System.out.flush();
int decision = 0;
System.out.println("Welcome to GuardSearch, our little slice of Google.\n");
while ((decision != 1) || (decision != 2)){
System.out.println("Please enter the number of what you would like to do from the following list:");
System.out.println("1. Submit knowledge.");
System.out.println("2. Search.");
System.out.println("3. Quit.");
decision = scan.nextInt();
if (decision == 1) {
Submit submit = new Submit();
submit.takeinfo();
break;
}
else if (decision == 2){
Search search = new Search();
search.takekeywords();
break;
}
else if (decision == 3){
leave = true;
break;
}
}
}
scan.close();
}
}
Thanks in advance. I have researched this issue and found no occurrences relevant to my exact issue.
EDIT: Here is my Submit and Search class as requested:
import java.io.*;
import java.util.Scanner;
public class Submit {
public static void takeinfo() {
final String ANSI_CLS = "\u001b[2J";
final String ANSI_HOME = "\u001b[H";
System.out.print(ANSI_CLS + ANSI_HOME);
System.out.flush();
System.out.println("Submit your knowledge to the system.\n");
Scanner sc = new Scanner(System.in);
int decision = 0;
while ((decision != 1) || (decision != 2)){
System.out.println("1. Change an existing article.");
System.out.println("2. Create a new article.");
System.out.println("3. Delete an article.");
System.out.println("4. Back.");
decision = sc.nextInt();
if (decision == 1) {
ChangeArticle chngArt = new ChangeArticle();
chngArt.takeinfo();
break;
}
else if (decision == 2){
CreateArticle createArt = new CreateArticle();
createArt.title();
break;
}
else if (decision == 3){
DeleteArticle deleteArt = new DeleteArticle();
deleteArt.takeinfo();
break;
}
else if (decision == 4){
GuardSearch gs = new GuardSearch();
gs.Menu();
break;
}
else {
System.out.println("Please enter a valid number.\n");
}
}
sc.close();
}
}
And the Search class:
import java.util.*;
import java.io.*;
public class Search {
Scanner sc = new Scanner(System.in);
public void takekeywords() {
final String ANSI_CLS = "\u001b[2J";
final String ANSI_HOME = "\u001b[H";
System.out.print(ANSI_CLS + ANSI_HOME);
System.out.flush();
System.out.println("Search the system.\n");
boolean fin = false;
int dec;
while (fin != true){
System.out.println("Please select which search type you want:\n");
System.out.println("1. Keywords.");
System.out.println("2. Category listing.");
System.out.println("3. Back\n");
dec = sc.nextInt();
if (dec == 1) {
// Do a keyword thing
fin = true;
}
else if (dec == 2) {
// Do a category thing
searchCategories();
fin = true;
}
else if (dec == 3) {
GuardSearch gs = new GuardSearch();
gs.Menu();
break;
}
}
}
public void searchCategories(){
// Create an empty list of subcategories, that will be added to when the user wants to add sub categories
LinkedList<Category> newSubCategories = new LinkedList<Category>();
// Create a list of .txt's relevant to the category
LinkedList<String> relevantArticles = new LinkedList<String>();
relevantArticles.add("example.txt");
LinkedList<String> dirListing = new LinkedList<String>();
//System.out.println("Please select your category:\n");
String s = "Example Category";
// Create the first category, passing in its name, an empty list of subCategories (which are of type Category), and a list of .txt's relevant to the category
Category firstCategory = new Category(s, newSubCategories, relevantArticles);
File wd = new File("/bin");
Process proc = null;
try {
proc = Runtime.getRuntime().exec("/bin/bash", null, wd);
}
catch (IOException e) {
e.printStackTrace();
}
if (proc != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
out.println("cd /var/tmp/cholland/GuardSearch/");
out.println("ls *.art");
out.println("exit");
String line;
System.out.println();
try {
int x = 1;
while ((line = in.readLine()) != null) {
System.out.println(x + ") " + line);
dirListing.add(line);
x++;
}
System.out.println("Please select the article you want:\n");
int dec = sc.nextInt();
//System.out.println(Arrays.toString(dirListing.toArray()));
System.out.println(dirListing.size());
try {
for (int y=1; y<=dirListing.size(); y++) {
if (y == dec){
boolean fin = false;
while (fin != true){
System.out.println("You chose: " + (dirListing.get(boundIndex(y))) + ". Opening file...");
System.out.println("===========================================================\n");
String text;
String filepath = ("/var/tmp/cholland/GuardSearch/" + (dirListing.get(boundIndex(y))));
BufferedReader br = null;
StringBuffer contents = new StringBuffer();
try {
br = new BufferedReader(new FileReader(filepath));
text = null;
while ((text = br.readLine()) != null) {
contents.append(text).append(System.getProperty("line.separator"));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
text = (contents.toString());
System.out.println(text);
System.out.println("\n===========================================================\n");
fin = true;
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
proc.waitFor();
out.close();
in.close();
proc.destroy();
}
catch (Exception e) {
e.printStackTrace();
}
}
sc.close();
}
public int boundIndex(int x){
if (x != 0){
return (x - 1);
}
else {
return 0;
}
}
}

I think the problem is here decision = scan.nextInt();
NoSuchElementException will be thrown if no more tokens are available. This is caused by invoking nextInt() without checking if there's any integer available. You can hasNextInt() to check if any more tokens are available.
Something like:
if(scan.hasNextInt() )
decision = scan.nextInt(); // if there is another number
else
decision = 0; // nothing added in the input

The cause of the error is that you are closing the scanner at the end of searchCategories.

Related

Press any key with BufferedReader

I created a java file called Product.java. I also created a text file called Items.txt. Basically when the user enter the word using sequential search to search the data what they are looking from Items.txt. My main problem is when I enter 3 to display all the records or enter x to exit the program, it keeps on looping. But I don't how to resolve this problem. Can anyone solved this for me?
Items.txt
1000|Cream of Wheat|Normal Size|Breakfast|NTUC|5|3.00
1001|Ayam Brand|Small Size|Canned|NTUC|4|4.00
Product.java
import java.io.*;
import java.util.*;
public class Product {
public static void main(String[] args) {
ArrayList<Item> prdct = new ArrayList<Item>();
String inFile = "items.txt";
String line = "";
FileReader fr = null;
BufferedReader br = null;
StringTokenizer tokenizer;
int quantity;
String id, brandname, desc, category, supplier;
float price;
try{
fr = new FileReader(inFile);
br = new BufferedReader(fr);
line = br.readLine();
while(line!=null)
{
tokenizer = new StringTokenizer(line,"|");
id = tokenizer.nextToken();
brandname = tokenizer.nextToken();
desc = tokenizer.nextToken();
category = tokenizer.nextToken();
supplier = tokenizer.nextToken();
quantity = Integer.parseInt(tokenizer.nextToken());
price = Float.parseFloat(tokenizer.nextToken());
Item itm = new Item(id,brandname,desc,category,supplier,quantity,price);
prdct.add(itm);
line = br.readLine();
}
br.close();
}
catch(FileNotFoundException e){
System.out.println("The file " + inFile + " was not found.");
}
catch(IOException e){
System.out.println("Reading error!");
}
finally
{
if (fr!=null){
try
{
fr.close();
}
catch(IOException e)
{
System.out.println("Error closing file!");
}
}
}
String INPUT_PROMPT = "\nPlease enter 3 to display all records, 4 to insert record, 5 to remove old records " + "or enter 'x' to quit.";
System.out.println(INPUT_PROMPT);
try
{
BufferedReader reader = new BufferedReader
(new InputStreamReader (System.in));
line = reader.readLine();
while(reader != null)
{
for(int i=0; i<prdct.size(); i++)
{
if(prdct.get(i).id.contains(line) || prdct.get(i).brandname.contains(line) || prdct.get(i).desc.contains(line)
|| prdct.get(i).category.contains(line) || prdct.get(i).supplier.contains(line))
{
System.out.println(prdct.get(i));
}
System.out.println(INPUT_PROMPT);
line = reader.readLine();
}
}
while("3".equals(line))
{
for(int i=0; i<prdct.size(); i++)
{
System.out.println(prdct.get(i));
}
System.out.println(INPUT_PROMPT);
line = reader.readLine();
}
while(!line.equals("x"))
{
System.out.println(INPUT_PROMPT);
line=reader.readLine();
}
}
catch(Exception e){
System.out.println("Input Error!");
}
}
}
The problem is with this loop:
while(reader != null)
{
for(int i=0; i<prdct.size(); i++)
{
if(prdct.get(i).id.contains(line) || prdct.get(i).brandname.contains(line) || prdct.get(i).desc.contains(line)
|| prdct.get(i).category.contains(line) || prdct.get(i).supplier.contains(line))
{
System.out.println(prdct.get(i));
}
System.out.println(INPUT_PROMPT);
line = reader.readLine();
}
}
It keeps on looping while reader is not null and it will never be. You might want to try checking something else that suits your problem better, maybe:
While(!line.equals("3"))
While(!line.equals("x"))
While(line != null)
Otherwise, even if there is an 'x', '3' or simply nothing, still (reader != null) and therefore the loop is infinite.
I suspect that the newline character is what causes the comparison to fail.
Instead of checking if:
"3".equals(line)
Try:
"3".equals(line.trim())
Same applies to the following comparison.
Try changing this..
line = reader.readLine();
while(reader != null)
{
to this..
line = reader.readLine();
while(line != null)
{
You are looping on the reader being not null, which it always will be.
you have to define these functions:
public void showAllRecords() {
// show all record here
}
public void insertRecord() {
// insert record here
}
public void removeRecord() {
// insert record here
}
public void exit() {
// insert record here
}
then
do{
System.out.println(INPUT_PROMPT);
switch(line)
{
case "3":
showAllRecords();
break;
case "4":
insertRecord();
break;
case "5":
removeRecord();
}
}while(!line.equals('x'));

Implementing comparable java

I am trying to sort a list of user entered tasks and dates by date using comparable interface. I have the tasks in a external .txt file and am a little confused if I am accessing the correct variables. The program compiles, but when I try to sort the tasks, it seems to erase the contents of the file. Here is what I have:
public class DueDate implements Comparable<DueDate>{
public String addedTask = "";
public String enteredDueDate;
public DueDate(String addedTask, String dueDate){
this.addedTask = addedTask;
this.enteredDueDate = enteredDueDate;
}
public String toString(){
return addedTask+"\t"+enteredDueDate+"\t";
}
#Override
public int compareTo(DueDate o) {
return this.enteredDueDate.compareTo(o.enteredDueDate);
}
}
public class Main {
public static String fileName = "/Users/eringray/Desktop/tasklistjava/src/javatask.txt";
public static void main(String[] args) throws IOException {
int menuItem = -1;
while(menuItem != 0){
menuItem = menu();
switch (menuItem){
case 1:
showTaskList();
break;
case 2:
addTask();
break;
case 3:
sortList();
case 4:
deleteTasks();
break;
case 0:
break;
default:
System.out.println("Invalid Input");
}
}
}
static int menu(){
int choice;
Scanner sc = new Scanner(System.in);
System.out.println("\n Task List Menu \n");
System.out.println("0: Exit Menu");
System.out.println("1: Show Tasks in List");
System.out.println("2: Add Task to List");
System.out.println("3: Sort Tasks by Due Date");
System.out.println("4: Delete Tasks");
System.out.println();
System.out.println("Enter a choice: ");
choice = sc.nextInt();
return choice;
}
static void showTaskList(){
System.out.println("\nTask List\n");
try {
Scanner inFile = new Scanner(new FileReader(fileName));
String line;
int number = 1;
while(inFile.hasNextLine()){
line = inFile.nextLine();
System.out.println(number + ". " + line);
++number;
}
System.out.println();
inFile.close();
} catch (FileNotFoundException ioe) {
System.out.println(ioe);
}
}
static void addTask(){
System.out.println("\nAdd Task\n");
try {
Scanner input = new Scanner(System.in);
PrintWriter outFile = new PrintWriter(new FileWriter(fileName, true));
System.out.println("Enter a Task: ");
String addedTask = input.nextLine();
System.out.println("Set Due Date for this Task(yyyy-mm-dd): ");
String dueDate = input.nextLine();
outFile.println(addedTask + "\t" + dueDate);
outFile.close();
} catch (IOException ioe) {
System.out.println(ioe);
}
}
static void sortList() throws IOException {
System.out.println("\nSorted List\n");
try {
BufferedReader br = new BufferedReader(new FileReader(fileName));
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName, true));
ArrayList<DueDate> tasks = new ArrayList<DueDate>();
String line = "";
while((line = br.readLine()) != null) {
String[] values = line.split("\t");
if(values.length == 2) {
String addedTask = values[0];
String enteredDueDate = values[1];
DueDate d = new DueDate(addedTask, enteredDueDate);
tasks.add(d);
}
}
Collections.sort(tasks);
for(int i = 0; i < tasks.size(); i++){
DueDate date = tasks.get(i);
String lineText = date.toString();
bw.write(lineText);
bw.newLine();
}
br.close();
bw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private static void deleteTasks(){
PrintWriter writer = null;
try {
writer = new PrintWriter(fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
assert writer != null;
writer.print("");
writer.close();
}
}
Sorry for the extra code, but thought it might help you see what I'm trying to do. Any suggestions would be great. I am new to Java, so please be patient with me! Thanks!
The problem is a missing break statement in your switch which is calling the deleteTasks() method after calling sortList(). Change your code to this and it should work fine:
int menuItem = -1;
while(menuItem != 0){
menuItem = menu();
switch (menuItem){
case 1:
showTaskList();
break;
case 2:
addTask();
break;
case 3:
sortList();
break; //The missing break
case 4:
deleteTasks();
break;
case 0:
break;
default:
System.out.println("Invalid Input");
}
}
And the constructor of the DueDate class is missing the assignment of the enteredDueDate variable since the parameter was named dueDate and not enteredDueDate. You should change it to something like this:
public DueDate(String addedTask, String enteredDueDate){
this.addedTask = addedTask;
this.enteredDueDate = enteredDueDate;
}
since you are currently assigning the member variable to it's own value.
You should also consider changing the sortList method, especially the BufferedWriter or it will duplicate the list each time you call it. Something like this sould do it:
BufferedReader br = new BufferedReader(new FileReader(fileName));
ArrayList<DueDate> tasks = new ArrayList<DueDate>();
String line = "";
while((line = br.readLine()) != null) {
String[] values = line.split("\t");
if(values.length == 2) {
String addedTask = values[0];
String enteredDueDate = values[1];
DueDate d = new DueDate(addedTask, enteredDueDate);
tasks.add(d);
}
}
Collections.sort(tasks);
br.close();
//Changed it to not append but overwrite the old file so it only contains the sorted list
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName, false));
for (DueDate date : tasks) {
String lineText = date.toString();
bw.write(lineText);
bw.newLine();
}
bw.flush();
bw.close();
EDIT:To print the sorted list out there are a few things you could do.
The easiest way would probably be to append a call of the showTaskList method to the end of the sortList method like this
//...
bw.flush();
bw.close();
showTaskList();
} catch (FileNotFoundE
e.printStackTrace(
}
or you could loop through the ArrayList and print them out like this:
//...
bw.flush();
bw.close();
for (int i = 0; i < tasks.size(); i++) {
DueDate dueDate = tasks.get(i);
System.out.println(i+". "+dueDate.toString());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
EDIT 2: The easiest way to get all Tasks with empty DueDate to the bottom when sorting is to change the compareTo method in DueDate class:
#Override
public int compareTo(DueDate o) {
return -this.enteredDueDate.compareTo(o.enteredDueDate);
}
Just negate it so all entries are sorted descending and those with empty DueDate will be at the end of the list (it relays on how strings are compared by default).
But if you want to use Tasks with no due date you'll run into a problem in your sortList method since the split("\t")method will only return an array with length 1 and your if condition would fail. One way to solve it looks like this:
//...
while ((line = br.readLine()) != null) {
String[] values = line.split("\t");
//To ensure it's still valid data
if (values.length >= 1 && values.length <= 2) {
String addedTask = values[0];
String enteredDueDate;
//Check whether dueDate has a value or is empty
if (values.length == 1)
enteredDueDate = "";
else
enteredDueDate = values[1];
DueDate d = new DueDate(addedTask, enteredDueDate);
tasks.add(d);
}
}
//...
or more compact version (does exactly the same thing)
//...
while ((line = br.readLine()) != null) {
String[] values = line.split("\t");
if (values.length >= 1 && values.length <= 2)
tasks.add(new DueDate(values[0], values.length == 1 ? "" : values[1]));
}
//...
Hope this helps (:

dictionary in java using java.io

I have written code of dictionary in java in which i read data from file named newFile.txt .In file world is placed on one line and its meaning is placed on nextline. User enters a world. If word is found in file it shows its meaning placed on next line and if word is not found it shows similar words (substrings).
"While searching word it should not search meaning."
import java.io.*;
import java.util.*;
public class Notepad {
public static void main(String []args) throws IOException{
BufferedReader in = null;
Scanner input = new Scanner(System.in);
String str;
boolean notfound = false;
char again = 'a';
try{
do{
notfound = false;
System.out.println("Enter word :");
str = input.next();
File f = new File("D:\\newFile.txt");
in = new BufferedReader(new FileReader(f));
String s;
while((s = in.readLine()) != null){
int x = s.indexOf(str);
if(x != -1){
int lens = s.length();
String sub = s.substring(x);
int lensub = str.length();
if(lens == lensub){
System.out.println((in.readLine()));
break;
}
else{
System.out.println(sub) ;
notfound = true;
}
}
s = in.readLine();
}
if(!notfound){
System.out.println("Try another world?(y/n):");
again = input.next().trim().charAt(0);
again = Character.toLowerCase(again);
}
}
while(notfound || again == 'y');
System.out.println("terminated!");
}
finally{
if(in != null){
in.close();
}
}
}
}
when i enters a substring of a word it searches meaning as well and then if a enter right word it does not show meaning
//This code is reading a file that is situated like this:
Hello - to greet
Circle - a round shape
//Then the code can be done like so, is this ok?
public static void main(String []args) throws IOException{
BufferedReader in = null;
Scanner input = new Scanner(System.in);
String str;
boolean notfound = false;
char again = 'a';
try{
do{
notfound = false;
System.out.println("Enter word :");
str = input.next();
File f = new File("/Folder/demo1.txt");
in = new BufferedReader(new FileReader(f));
String s;
while((s = in.readLine()) != null){
int x = s.indexOf(str);
// System.out.println("Index of dash:" + s.indexOf("-"));
// System.out.println("Index of Hello:" + x);
if(x != -1 && x<s.indexOf("-")){
String sub = s.substring(0,s.indexOf("-"));
System.out.println("Sub:" + sub);
System.out.println("Str:" + str);
if(sub.trim().equals(str.trim())){
System.out.println("Success:" +sub);
notfound = true;
break;
}
else{
System.out.println("Word is not present") ;
notfound = false;
break;
}
}
}
if(!notfound){
System.out.println("Try another word?(y/n):");
again = input.next().trim().charAt(0);
again = Character.toLowerCase(again);
}
}
while(notfound || again == 'y');
System.out.println("terminated!");
}
finally{
if(in != null){
in.close();
}
}
}
}

Create method that opens a file, then lets's user write to file then end when pressing enter on empty line?

I want to create a method that which opens a file for writing, then prompts the user to enter lines of text until they press enter on an empty line to stop input.
It's giving some trouble in that I can get the method run and I can input text but it wont close or save? I hit return after my text to go to a blank line and hit return again but it just moves onto another line.
I have written the following but can't get it working correctly.
My code:
public void writeFile()
{
String myString;
clrscr();
System.out.println("Begin typing: ");
myString = Genio.getString();
FileOutputStream outputStream = null;
PrintWriter printWriter = null;
// use a try-catch-finally block to catch file-related exceptions
try
{
outputStream = new FileOutputStream("writing.txt");
printWriter = new PrintWriter(outputStream);
printWriter.write(myString);
printWriter.newLine();
// write information to the file via the PrintWriter
while (myString != "")
{
printWriter.print(myString + " ");
}
}
catch (IOException e)
{
System.out.println("Sorry, there has been a problem opening or writing to the file");
}
finally
{
if (printWriter != null)
{
printWriter.close();
}
}
}
If it's needed, Genio is the class that deals with user input:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Genio
{
public Genio()
{
}
private static String getStr()
{
String inputLine = "";
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
try
{
inputLine = reader.readLine();
}
catch(Exception exc)
{
System.out.println ("There was an error during reading: "
+ exc.getMessage());
}
return inputLine;
}
public static int getInteger()
{
int temp=0;
boolean OK = false;
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
do
{
try
{
temp = Integer.parseInt(keyboard.readLine());
OK = true;
}
catch (Exception eRef)
{
if (eRef instanceof NumberFormatException)
{
System.out.print("Integer value needed: ");
}
else
{
System.out.println("Please report this error: "+eRef.toString());
}
}
} while(OK == false);
return(temp);
}
public static float getFloat()
{
float temp=0;
boolean OK = false;
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
do
{
try
{
temp = Float.parseFloat(keyboard.readLine());
OK = true;
}
catch (Exception eRef)
{
if (eRef instanceof NumberFormatException)
{
System.out.print("Number needed: ");
}
else
{
System.out.println("Please report this error: "+eRef.toString());
}
}
} while(OK == false);
return(temp);
}
public static double getDouble()
{
double temp=0;
boolean OK = false;
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
do
{
try
{
temp = Double.parseDouble(keyboard.readLine());
OK = true;
}
catch (Exception eRef)
{
if (eRef instanceof NumberFormatException)
{
System.out.print("Number needed: ");
}
else
{
System.out.println("Please report this error: "+eRef.toString());
}
}
} while(OK == false);
return(temp);
}
public static char getCharacter()
{
String tempStr="";
char temp=' ';
boolean OK = false;
do
{
try
{
tempStr = getStr();
temp = tempStr.charAt(0);
OK = true;
}
catch (Exception eRef)
{
if (eRef instanceof StringIndexOutOfBoundsException)
{
// means nothing was entered so prompt ...
System.out.print("Enter a character: ");
}
else
{
System.out.println("Please report this error: "+eRef.toString());
}
}
} while(OK == false);
return(temp);
}
public static String getString()
{
String temp="";
try
{
temp = getStr();
}
catch (Exception eRef)
{
System.out.println("Please report this error: "+eRef.toString());
}
return(temp);
}
}
You class works fine for the most part. I fixed the problematic part for you:
// write information to the file via the PrintWriter
while (!myString.equals(""))
{
myString = Genio.getString();
printWriter.print(myString + "\n");
}
First the condition inside the while was incorrect. MyString has to be compared using the equals operator (or using the isEmpty method).
Second, you need to keep reading into myString inside the loop, otherwise you get an infinite loop and it will never exit.
Third, you want want to add newlines to the output file, so I added them.
You only read myString once, before the while loop starts.
You don't compare strings with == or !=
Change
while (myString != "") to while (!myString.equals(""))
You have an infinite loop, because you only read myString before you enter the while loop, so your condition will never be false.
Also, as Rishi Dua said, you can't compare strings with the usual == ou != operators, you have to use either .equals() or .isEmpty.
Comparing == and equals method.
Since java.lang.String class override equals method, It return true if two String object contains same content.
But,
== will only return true if two references are pointing to same object.
Modified code:
while (! myString.equals("")){
// Write your code here
myString = Genio.getString();
printWriter.print(myString + "\n");
}

BufferedReader not closing properly

I am working on a class called ConsoleInput which is supposed to simplify console input for an application I am developing. While testing it I have noticed that I can't seem to close the BufferedReader, and instantiate a new ConsoleInput class. I could get by without closing the BufferedReader, but it's an interesting problem nonetheless. I would like to learn why I can't close it, and what I can do to change that.
ConsoleInput class:
package frontend;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.io.*;
public class ConsoleInput {
private BufferedReader buf = null;
private boolean ignoreconfirm = false;
private boolean confirmation = false;
private boolean closed = false;
private String dateformat = "yyyy-MM-dd";
private boolean confirm(String value) throws IOException {
boolean accept = false;
boolean answer = false;
String l = "I";
while (!accept) {
System.out.print(l + "s '" + value + "' correct (Y/N) ?: ");
String line = buf.readLine();
line = line.trim();
line = line.toLowerCase();
if (line.equals("y") || line.equals("yes")) {
accept = true;
answer = true;
} else if (line.equals("n") || line.equals("no")) {
accept = true;
answer = false;
}
if (!accept) System.out.print("Try confirmation again, ");
l.toLowerCase();
}
return answer;
}
public String getString() throws IOException, ExcConsoleInputClosed {
if (closed) throw new ExcConsoleInputClosed();
boolean accept = false;
String line = null;
while (!accept) {
line = buf.readLine();
if (confirmation && !ignoreconfirm) {
accept = confirm(line);
if (!accept) System.out.print("Try input again: ");
} else {
accept = true;
}
}
return line;
}
public Integer getInt() throws IOException, ExcConsoleInputClosed {
boolean accept = false;
boolean parsed = false;
Integer value = null;
String input = null;
while (!parsed) {
if (confirmation) ignoreconfirm = true;
input = getString();
if (confirmation) ignoreconfirm = false;
input.trim();
if (confirmation) accept = confirm(input);
else accept = true;
if (!accept) System.out.print("Try input again: ");
else {
try {
value = new Integer(Integer.parseInt(input));
parsed = true;
} catch (NumberFormatException e) {
System.out.print("Error parsing your input, try again: ");
}
}
}
return value;
}
public Date getDate()
throws IOException, ExcConsoleInputClosed {
boolean accept = false;
boolean parsed = false;
Date value = null;
String input = null;
SimpleDateFormat format = new SimpleDateFormat(dateformat);
while (!parsed) {
if (confirmation) ignoreconfirm = true;
input = getString();
if (confirmation) ignoreconfirm = false;
input.trim();
if (input.equals("help")) {
System.out.println("Enter a date with format " + dateformat + ".");
} else {
if (confirmation) accept = confirm(input);
else accept = true;
if (!accept) System.out.print("Try input again: ");
else {
try {
value = format.parse(input);
parsed = true;
} catch (ParseException e) {
System.out.print("Error parsing your input, try again");
}
}
}
}
return value;
}
public void toggleConfirm() {
confirmation = !confirmation;
}
public boolean confirmation() { return confirmation; }
public void close() throws IOException {
closed = true;
buf.close();
}
public ConsoleInput() {
buf = new BufferedReader(new InputStreamReader(System.in));
}
}
Unit test for this class:
public class feConsoleInput {
public static void main(String[] args) {
ConsoleInput console = new ConsoleInput();
System.out.println("Fetching input from console.");
for (int c=0; c <= 1; c++) {
try {
System.out.print("Enter a string: ");
String text = console.getString();
System.out.println("You entered: " + text);
System.out.print("Enter a integer: ");
Integer number = console.getInt();
System.out.println("You entered: " + number);
System.out.println("Enter a date...");
Date date = console.getDate();
System.out.println("You entered: " + date.toString());
console.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExcConsoleInputClosed e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("");
console = new ConsoleInput();
console.toggleConfirm();
}
}
}
When it runs the second time after closing I get this IOException for the Stream being closed. The ConsoleInput class constructor as far as I know should have opened a new one.
Fetching input from console.
Enter a string: A string of input.
You entered: A string of input.
Enter a integer: 42
You entered: 42
Enter a date...
2012-12-07
You entered: Fri Dec 07 00:00:00 EST 2012
java.io.IOException: Stream closed
Enter a string:
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:162)
at java.io.BufferedInputStream.read(BufferedInputStream.java:325)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:282)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:324)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:176)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:153)
at java.io.BufferedReader.readLine(BufferedReader.java:316)
at java.io.BufferedReader.readLine(BufferedReader.java:379)
at frontend.ConsoleInput.getString(ConsoleInput.java:45)
at test.feConsoleInput.main(feConsoleInput.java:17)
When you close the BufferedInputStream, it also closes the underlying System.in stream too. This cannot be undone.
A common solution is to wrap System.in with a CloseShieldInputStream to avoid it being closed when you close the outer reader.
public ConsoleInput() {
buf = new BufferedReader(new InputStreamReader(
new CloseShieldInputStream(System.in)));
}
Alternatively, just keep one instance of your ConsoleInput class alive for your entire program duration.

Categories