my BufferedReader character input loop program keeps running forever - java

I wrote a program which prints out the characters of the sentence (or word) wrote by the user to the console. I thought that the program will end after I gave the first input. But it didn't and kept taking inputs and printing it even after it printed the first sentence. Can you explain me why it happened so? I am new to this. Here is the program:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
/*
* This program prints out the characters written in the console
* line by line.
*/
public class ReaderProgram {
public static void main(String args[]) throws IOException{
char c;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
do{
//reads character and stores it in c
c = (char) br.read();
//prints out c
System.out.println(c);
}while(c != -1);
//'while' checks if c is -1 (-1 means end of the stream)
}
}
Output is shown here (Input to console is show like this):
Epic
E
p
i
c
Dream
D
r
e
a
m

You have cast the result of br.read() too early.
br.read() returns a int, which has a larger storage capacity than a char. char is neither signed nor large enough to store both -1 and the full UTF-16 range of values.
By casting the result to a char before comparing it to -1 you have effectively converted -1 to Character.MAX_VALUE. Which can never equal -1.
Consider the following code:
public static void main( String[] args ) {
char v = (char) -1;
System.out.println( "v = " + (int) v );
}
It will print 65535, and not -1.

Related

Why empty lines are being printed at the when I use BufferedReader to read characters from the console and print them?

Here is my program.
// Here we use a BufferredReader to read characters from console.
package fileIO;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class BRRead {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char ch;
System.out.println("Enter characters, 'q' to quit.");
do {
ch = (char)br.read();
System.out.println(ch);
} while(ch!='q');
}
}
Input 1: testq
Output:
t
e
s
t
q
Input 2: test
Output:
t
e
s
t
""
""
""
""
where "" means empty line.
My question is why 4 empty lines are printed for the case when the input characters doesn't contain letter 'q' but aren't printed when the input characters contain letter 'q'?
Complete-er answer at the bottom
Haven't run it at all to check, though it seems like it could have something to do with the use of a do-while loop instead of a while loop
This format will make sure that the character 'q' is not read before it attempts to output anything
while(ch!='q')
{
System.out.println(ch);
ch = (char)br.read();
}
And this format prints the read character before testing if it is valid
do {
ch = (char)br.read();
System.out.println(ch);
} while(ch!='q');
EDIT after some trial/error
With this version, I have used the Scanner class which is quite similar, and I am more familiar with it. It may go something like so:
Create Object(s) for reading the data BufferedReader,Scanner,etc.
Check if there is content present
Accept the data as a String and read the first character
Output if the String is is not q
Cycle the test-> read -> print -> loop, till q is entered
Scanner input = new Scanner(System.in);
System.out.println("Enter characters, 'q' to quit.");
String read = input.nextLine();
while(read.length() <= 1 && read.charAt(0) != 'q')
{
System.out.print(read);
read = input.nextLine();
}
The (almost) original method*
Eureaka!
name.read() Reads a single character --
However, this returns an int datatype which cannot be converted with the (char) mask.
name.readLine() Reads a line of text -- With this, you can simply take the character at index 0
https://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html
do {
full = br.readLine();
System.out.print(full);
} while(full.length() <= 1) && full.charAt(0) != 'q');
Not sure what the best way to do it would be between a do-while and a while loop, and that may ultimately come down to use case and opinion. and you may want to make a boolean method too
// true if String matches 'q' or "quit"
public static boolean isQuit(input)
{
String lowercase = input.toLower();
char start = input.charAt(0);
return (lowercase.equals("quit")
|| (input.length() <= 1 && start == 'q'));
}

Basic Java program giving wrong ouput

I'm getting just spaces after running this code, it is not even printing "ABC"..
import java.io.*;
class Str{
public static void main( String args[])
{
String a = "abc";
char ch[] = new char[2];
a.getChars(0,0,ch,1);
PrintWriter pw = new PrintWriter(System.out);
pw.println(ch);
pw.println("ABC");
pw.println(ch);
System.out.println(ch);
}
}
getChars uses parameters (int srcBegin, int srcEnd, char[] dest, int destBegin). Your srcBegin and srcEnd are both 0.
srcBegin needs to be 0 in your case, but srcEnd needs to be 3.
This works:
a.getChars(0,3,ch,0);
And you need a char array with the length 3 and not 2, so change char ch[]=new char[2] to char ch[]=new char[3]
To copy only the first character into the ch array at index 1:
a.getChars(0,1,ch,1);
It seems you are lacking calling pw.flush(), then something shows up. That should be the result of your program. You might have to change parameters in String.getChars() method according to this Java tutorial, as you are receiving an empty array.
String a="abc";
char ch[]=new char[2];
a.getChars(1,2,ch,1); //Put indexes to first 2 positions to mark srcBegin, srcEnd
PrintWriter pw=new PrintWriter(System.out);
pw.println(ch);
pw.println("ABC");
pw.println(ch);
pw.flush();

ArrayIndexOutOfBoundsException on a Split String in a array

So I am doing some problems on the UVa online problem judge, but on a relativity easy problem, I keep on getting a ArrayIndexOutOfBoundsException. To understand the code, here is the problem.
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int t = scan.nextInt();
int sum = 0;
for (int i = 0; i <= t; i++){
String d = scan.nextLine();
if (d.equals("report")) {
System.out.println(sum);
} else {
String[] parts = d.split(" ");
int z = Integer.parseInt(parts[1]);
sum+=z;
}
}
}
}
The error message is:
reportException in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Main.main(Main.java:16)
And I am using the sample input given.
Edit:
I have already tried added println statements in the code and figured out that the number is not being read. I am trying to understand why.
OK, after some messing around on my machine I think I found what might be at least part of the problem. The issue is that I'm not sure what the precise input is, so I'm going off of what I could get working on my machine.
So you start up your program, and it waits for a prompt at this line:
int t = scan.nextInt();
You enter your integer, and the program moves on as expected:
Input: 100 // Then press enter to continue
The input is parsed, and now t is set to 100.
Then when your program enters your for loop, it comes across this line:
String d = scan.nextLine();
Yet for some reason the program doesn't wait for input! (Or at least it didn't on my machine)
I believe the issue lies here:
Input: 100 // Then press enter to continue
^^^^^^^^^^^
What I think is happening is that your input is really
Input: 100\n
^^
That character (\r\n on Windows) is what's input when you hit enter. It's a newline character that tells the console to go to the next line.
So as a result, what I think happens is this:
Input: 100\n
Scanner parses 100, leaving the \n in the input stream
Then at the nextLine() call, the scanner sees \n on the input stream, which denotes end of line, so it thinks you already input the entire line! Because what it thought was your input was only the newline character, it returns an empty string, because your "input" was an empty string and the newline character. Your program then goes to split the newline character by spaces, rightly returns an array with a single element, and then your program promptly crashes when accessing an out-of-bounds index.
What might work better is reading an entire line first and parsing the integer so your scanner doesn't get ahead of itself, like this:
int t = Integer.parseInt(scan.nextLine());
Just as a warning: This is what I've been able to come up with based on using OP's code as-is on my machine. I was unable to get a situation where the only element in parts was "donate". I will update further as I get more info.
The error message means the array parts's length less than 2, sometimes.
It means the variable d does not always contain the string BLANK SPACE, " ", what you split by.
try this code:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int t = scan.nextInt();
int sum = 0;
for (int i = 0; i <= t; i++){
String d = scan.nextLine();
if (d.equals("report")) {
System.out.println(sum);
} else {
String[] parts = d.split(" ");
/*
* Add IF statement,
*/
if (parts.length() > 1) {
int z = Integer.parseInt(parts[1]);
sum+=z;
}
}
}
}
}

Converting Letters to Numbers 2

Refer to Converting Letters to Numbers
In the file test.in.rtf, I have 'abcd' typed. However, when I run the program, I get ??? ??????????? ???????? plus maybe a few more in test.out.rtf. Why is this? Am I missing something?
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.StringTokenizer;
public class Test {
public static void main(String[] args) throws IOException {
BufferedReader f = new BufferedReader(new FileReader("test.in.rtf"));
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("test.out.rtf")));
StringTokenizer st = new StringTokenizer(f.readLine());
StringBuilder sb = new StringBuilder();
for (char c : st.nextToken().toCharArray()) {
sb.append((char)(c - 'a' + 1));
}
out.println(sb); // output result
out.close(); // close the output file
System.exit(0);
}
}
I'm pretty sure you want
sb.append(Integer.toString(c - 'a' + 1));
or simply
sb.append( c - 'a' + 1 );
which implicitly does the same thing, since the expression c - 'a' + 1 is implicitly cast to an int since Java does all non-long integer math (anything involving chars, bytes, shorts, and/or ints) by converting everything to ints first.
What you had cast the integer result to a char, which would be represented by the character whose ASCII value is that number (something b/w 1 and 26), which isn't something readable.
You are trying to write the char values 1,2,3 and 4 ('a'-'a' + 1 = 1 and so on), which are all "unwriteable" hence the "?"s. Why you get 7 and not 4? I don't know - maybe a locale issue or 3 of them are just written as two "?".

How to pass Keyboard Input (int) in Java to String?

I have a text file having names separated by tab. I need to print the name at the given input number. like i have
abc def ghi jkl mno
when the user enters 2, it should print "def". What i did is
import java.io.*;
import java.util.*;
public class NamesTab {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char ch;
System.out.println("Enter the Number: ");
ch=(char) br.read();
System.out.println(ch);
BufferedReader s = new BufferedReader(new FileReader("Ass1.txt"));
String c=s.readLine();
String[] tokens = c.split("\t");
System.out.println(tokens[1]);
}}
but i could not pass the "ch" to "tokens[ch]". please help me.
You can use ch-'0' for single-digit numbers.
System.out.println(tokens[ch-'0']);
You're attempting to provide a character in a space which should be an Integer. I understand that this "should" work in java, but just to be safe, cast ch to an int when you're getting the index of the String array containing the characters you want.
System.out.println(tokens[(int)ch]);
Can we assume that ch always refers to a number between 0 to 9? If so, ch - '0' should do the trick.

Categories

Resources