How to implement hasNext() method with BufferedReader + StringTokenizer? - java

I have this fast reader class:
static class FastReader {
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
}
catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
}
catch (IOException e) {
e.printStackTrace();
}
return str;
}
int[] readArray(int n) {
int[] a = new int[n];
for(int i=0; i<n; i++) {
a[i] = nextInt();
}
return a;
}
}
I want to stop reading input as soon as I reach end of file. I know this can be done using scanner hasNext() method, How can I implement the same method for my reader class?
PS. I want to read input for this question:
https://www.spoj.com/problems/COINS/

You can set a mark() then try to read a line, if it is successful you could reset() to where you set the mark and return true and false otherwise.
You would also have to check if the current tokenizer has more tokens left. For example:
boolean hasNext() {
if (st != null && st.hasMoreTokens()) {
return true;
}
String tmp;
try {
br.mark(1000);
tmp = br.readLine();
if (tmp == null) {
return false;
}
br.reset();
} catch (IOException e) {
return false;
}
return true;
}
mark() takes readAheadLimit argument to limit the number of characters that can be read while having that mark set, you could increase that if you're dealing with long lines.

You can cover your code in a while loop with the condition that the user input is not null.
Example:
BuffedReader br = new BufferedReader(new InputStreamReader(System.in);
String key = "";
while((key = br.readLine()) != null)
{
//your code
}

Related

Java - Problems with returning an integer array

I'm trying to read a .txt file called Heights.txt, which contains a string of numbers, each separated by a ":". The method produces one error that I can't seem to figure out.
It says that "the method must return a result of type int[]", at the very first line of this code.
I don't understand why it says this, as integerHeightDataPoints should be an integer array at that point, and should be able to be returned to a int[] method?
public static int[] readFile(){
BufferedReader br = null;
String dataPoints;
try {
br = new BufferedReader(new FileReader("Path\\Heights.txt"));
}
catch(IOException e) {
System.out.println("Please enter data first");
System.exit(0);
}
try {
while((dataPoints = br.readLine()) != null) {
if (dataPoints.contains(":")) {
String[] heightDataPoints = dataPoints.split(":");
int[] integerHeightDataPoints = new int[heightDataPoints.length];
for (int i = 0; i < integerHeightDataPoints.length; i++) {
integerHeightDataPoints[i] = Integer.parseInt(heightDataPoints[i]);
}
return integerHeightDataPoints;
}
}
}
catch (IOException e) {
System.out.println("Error reading file");
e.printStackTrace();
}
}
It's because you don't return anything in second IOException case or (as #Exception_al mentioned) when while never triggers.
public static int[] readFile() {
BufferedReader br = null;
String dataPoints;
try {
br = new BufferedReader(new FileReader("/tmp/file1"));
} catch (IOException e) {
System.out.println("Please enter data first");
System.exit(0);
}
int[] integerHeightDataPoints = new int[0];
try {
while ((dataPoints = br.readLine()) != null) {
if (dataPoints.contains(":")) {
String[] heightDataPoints = dataPoints.split(":");
integerHeightDataPoints = new int[heightDataPoints.length];
for (int i = 0; i < integerHeightDataPoints.length; i++) {
integerHeightDataPoints[i] = Integer.parseInt(heightDataPoints[i]);
}
return integerHeightDataPoints;
}
}
} catch (IOException e) {
System.out.println("Error reading file");
e.printStackTrace();
}
return integerHeightDataPoints;
}

How to check that byte stream contains even number?

I'm new to Java and I need to create a method checking that byte stream contains even number. I've already written some code, but I think it's horrible, and don't know how to test it. It seems to me there is some short and efficient way to do that check...
public boolean isNumber(InputStream in) {
boolean evenNum = false;
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String input;
int num;
try {
input = reader.readLine();
num = Integer.parseInt(input);
if (num % 2 == 0) {
evenNum = true;
}
} catch (IOException e) {
e.printStackTrace();
}
return evenNum;
}

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

Start with new line after certain amount of characters in java

I have a program which reads a file I can change the content of this file and after that it's written to another file. The input file looks like this: http://gyazo.com/4ee1ade01378238e2c765e593712de7f and the output has to look like this http://gyazo.com/5a5bfd00123df9d7791a74b4e77f6c10 my current output is http://gyazo.com/87a83f4c6d48aebda3d11060ebad66c2 so how to change my code that it's starts a new line after 12 characters? Also I want to delete the last !.
public class readFile {
String line;
StringBuilder buf = new StringBuilder();
public void readFile(){
BufferedReader reader = null;
try {
File file = new File("C:/Users/Sybren/Desktop/Invoertestbestand1.txt");
reader = new BufferedReader(new FileReader(file));
//String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
//buf.append(line);
processInput();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
};
}
}
public void processInput(){
buf.append(line);
if (buf.length()>7){
buf.append("-");
//buf.append(System.getProperty("line.separator"));
}
/* start with a new line if the line length is bigger than 12 - in progress*/
/* I know this if doesn't work but how to fix it? */
if (buf.length()>12){
buf.append(System.getProperty("line.separator"));
}
/* if a * is followed by * change them to a !*/
for (int index = 0; index < buf.length(); index++) {
if (buf.charAt(index) == '*' && buf.charAt(index+1) == '*') {
buf.setCharAt(index, '!');
buf.deleteCharAt(index+1);
//buf.deleteCharAt(buf.length()-1);
}
// get last character from stringbuilder and delete
//buf.deleteCharAt(buf.length()-1);
}
}
public void writeFile() {
try {
String content = buf.toString();
File file = new File("C:/Users/Sybren/Desktop/test.txt");
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Update the code in which while reading the file you will take the decision :
int sevenCount = 0;
int fourteenCount = 0;
int data = 0;
while ((data = reader.read()) != -1) {
sevenCount++;
fourteenCount++;
if(sevenCount==7)
{
buf.append("-"); // append - at every 7th character
sevenCount = 0;
}
if(fourteenCount==14)
{
buf.append("\n"); // change line after evrry 14th character
fourteenCount = 0;
}
if(((char)data) == '*')
{
char c = '!'; //Change the code when char contain *
data = (int)c;
}
else
{
buf.append((char)data);
}
}
If you want to insert a newline in a string every 12 chars:
str = str.replaceAll(".{12}", "$0\n");

How do i skip comments with buffer reader?

I have written the following program to read from a file and skip comments, it works for single line comments, but not for multi line ones. Does anyone know why? I don't need to worry about "//" in Strings. And only java comments ie "//" and "/* */"
code:
import java.io.*;
public class IfCounter2
{
public static boolean lineAComment(String line)
{
if (line.contains("//"))
return true;
return false;
}
public static boolean multiLineCommentStart(String line)
{
if (line.contains("/*"))
return true;
return false;
}
public static boolean multiLineCommentEnd(String line)
{
if (line.contains("*/"))
return true;
return false;
}
public static void main(String[] args) throws IOException
{
String fileName = args[0];
int numArgs = args.length;
int ifCount = 0;
// create a new BufferReader
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
line = reader.readLine();
// read from the text file
boolean multiLineComment = false;
while (( line = reader.readLine()) != null)
{
if (!multiLineCommentStart(line))
{
multiLineComment = true;
}
if (multiLineComment) {
if (!multiLineCommentEnd(line))
{
multiLineComment = false;
}
}
if (!lineAComment(line) && !multiLineComment)
{
stringBuilder.append(line);
stringBuilder.append(ls);
}
}
// create a new string with stringBuilder data
String tempString = stringBuilder.toString();
System.out.println(stringBuilder.toString());
}
}
You only set multiLineComment to true when !multiLineCommentStart(line) is true - that is, whenever the line does not contain /*.
Basically, your code should look sth like this (untested)
boolean multiLineComment = false;
while (( line = reader.readLine()) != null)
{
if (multiLineCommentStart(line))
{
multiLineComment = true;
}
if (multiLineComment) {
if (multiLineCommentEnd(line))
{
multiLineComment = false;
}
}
if (!lineAComment(line) && (multiLineComment == false))
{
stringBuilder.append(line);
stringBuilder.append(ls);
}
}
in that last if statement, you need to have an expression with your variable and a fixed
Andy's answer is right on the money but needs a validation in last if to make sure you are not counting */ as a valid line:
boolean multiLineComment = false;
while (( line = reader.readLine()) != null)
{
if (multiLineCommentStart(line))
{
multiLineComment = true;
}
if (multiLineComment) {
if (multiLineCommentEnd(line))
{
multiLineComment = false;
}
}
if (!lineAComment(line) && (multiLineComment == false) &&
!multiLineCommentEnd(line) )
{
stringBuilder.append(line);
stringBuilder.append(ls);
}
}

Categories