BufferedReader not closing properly - java

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.

Related

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 (:

Loop a search for a string using BufferedReaders?

I'm using two BufferedReaders, one to read a document, and another one to get the input of the String to search from user, heeding the advice here. Here's the code so far:
import java.io.*;
import java.util.*;
public class Ejercicio6 {
public static void main(String[] args) {
Character answer = 'S';
boolean exit = false;
String name;
String line;
Scanner sc = new Scanner (System.in);
boolean found = false;
File file = new File ("/test/Ejercicio6/nombres.txt");
try {
do{
exit = false;
FileInputStream fis = new FileInputStream(file);
BufferedReader readFile = new BufferedReader(new FileReader(file));
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Search a name, I'll tell you if it's found:");
name = userInput.readLine();
while ((line = readFile.readLine()) != null && found == false){
if(line.equals(name)) {
found = true;
}else
found = false;
}
if (found == true)
System.out.println("I have found the name " +name+ " in the file " +file.getName());
if (found == false)
System.out.println("Can't find the name");
fis.getChannel().position(0);
fileRead = new BufferedReader(new InputStreamReader(fis));
System.out.println("Do you want to try again? (Y/N)");
answer = sc.nextLine().toUpperCase().charAt(0);
if (answer =='S'){
exit = false;
}else
exit = true;
fileRead.close();
}while (exit == false);
// }catch (FileNotFoundException e) {
// e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
}
There are 3 names on the document, but I always get the "name found" print, regardless of the input matching or not. I'm trying to figure out how does the getChannel() and the buffer clearing, as told here, but I'm having lots of trouble. What I'm missing?
You need to unset your flag found to false again after you're printing for matched or unmatched name.
Just add
found = false;
before
fis.getChannel().position(0);
if (line.equals(name)) {
found = true;
} else
found = false;
can simplied:
found = line.equals(name);
Just move boolean found = false; right before while loop
package com.company;
import java.io.*;
import java.util.Scanner;
public class Ejercicio6 {
public static void main(String[] args) {
Character answer;
boolean exit;
String name;
String line;
Scanner sc = new Scanner(System.in);
File file = new File("file.txt");
try {
do {
FileInputStream fis = new FileInputStream(file);
BufferedReader readFile = new BufferedReader(new FileReader(file));
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Search a name, I'll tell you if it's found:");
name = userInput.readLine();
boolean found = false;
while ((line = readFile.readLine()) != null && found == false) {
found = line.equals(name);
}
if (found == true)
System.out.println("I have found the name " + name + " in the file " + file.getName());
if (found == false)
System.out.println("Can't find the name");
fis.getChannel().position(0);
BufferedReader fileRead = new BufferedReader(new InputStreamReader(fis));
System.out.println("Do you want to try again? (Y/N)");
answer = sc.nextLine().toUpperCase().charAt(0);
exit = answer != 'S';
fileRead.close();
} while (exit == false);
// }catch (FileNotFoundException e) {
// e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Java NoSuchElementException for Scanner in while loop [duplicate]

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.

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");
}

Using txt file input in a different class in java

I am having this issue getting the file input from one class and using it in another. So what happens is I have a file called readFile.java that reads in the line of a txt file. I have another file that I am using to evaluate a stack that I want to use the file input. So all in all, I am trying to find a way to replace my testInput string in my evalStack.java file with the file input from the readFile.java.
Here is the readFile.java:
import java.util.Scanner;
import java.io.*;
public class readFile {
String fname;
public readFile() {
System.out.println("Constructor");
getFileName();
readFileContents();
}
public void readFileContents()
{
boolean looping;
DataInputStream in;
String line;
int j, len;
char ch;
/* Read input from file and process. */
try {
in = new DataInputStream(new FileInputStream(fname));
looping = true;
while(looping) {
/* Get a line of input from the file. */
if (null == (line = in.readLine())) {
looping = false;
/* Close and free up system resource. */
in.close();
}
else {
System.out.println("line = "+line);
j = 0;
len = line.length();
for(j=0;j<len;j++){
System.out.println("line["+j+"] = "+line.charAt(j));
}
}
} /* End while. */
} /* End try. */
catch(IOException e) {
System.out.println("Error " + e);
} /* End catch. */
}
public void getFileName()
{
Scanner in = new Scanner(System.in);
System.out.println("Enter file name please.");
fname = in.nextLine();
System.out.println("You entered "+fname);
}
}
This is the evalStack.java:
import java.util.Scanner;
import java.io.*;
public class evalStack {
static String testInput = "(6+3) + (3-2)";
//This is the line I want to replace with the input the readFile gives me.
public static void main(String[] args){
int maxLength = testInput.length();
stackOb eval = new stackOb(maxLength);
boolean test = false;
//Evaluate and check parenthesis
for(int i = 0; i < testInput.length(); i++)
{
char a = testInput.charAt(i);
if(a=='(')
{
eval.push(a);
}
else if(a==')')
{
if(eval.empty() == false)
{
eval.pop();
}
else
{
test = true;
System.out.println("The equation is a not valid one.");
System.exit(0);
}
}
else
{
continue;
}
}
if(eval.empty() == true && test == false)
{
System.out.println("The equation is a valid one.");
}
else
{
System.out.println("The equation is a not valid one.");
}
}
Add the line import readFile; to the top of evalStack.java
Change input: static String testInput = new readFile().readFileContents();
Change return type: public String readFileContents()
Replace j = 0; with return line;
That will make it evaluate the first line.

Categories