I'm doing test driven development which requires me to write a test function for a class that takes input from the user. Since the console input function stops for input during tests, I wrote the tests using an InputStream which uses a string.
String str="3\n2\n1\n4\n";
InputStream is = new ByteArrayInputStream(str.getBytes());
assertTrue(app.RunApp(is));
This leads to the calling of the function getChoice(InputStream i) which involves console input from a Scanner.
public int getChoice(InputStream i) throws IOException {
Scanner s=new Scanner(i);
s.useDelimiter("\n");
String y= s.next();
int x=Integer.parseInt(y);
return x;
}
I want the above code to take the numbers in the string one by one. But, what is happening is that it takes the first number properly and then, the position of the stream goes directly to the end of the stream which causes a NoSuchElementException. Please Help!
Use...
String y = s.nextLine(); // That will take the entire line instead of only 1st word
Related
I am getting error while taking input with Integer.parseInt(args[0]); error is in args section i know i can change it to scanner but i want to know this method.
Can anybody point out or show the solution to my problem?
class NegativeOutputException extends Exception{
private final int ex;
NegativeOutputException(int a){
ex = a;
}
public String toString(){
return "NegativeOutputException!("+ex+")";
}
}
public class practice6_creating_custom_exception {
public static void main(String args[]){
int x = Integer.parseInt(args[0]);//Error Here argument at position one
int y = Integer.parseInt(args[1]);//argument at position two
//argument at position twenty one which doesn't exsist
int a;
try{
a = x * y;
if(a < 0)
throw new NegativeOutputException(a);
System.out.println("Output >>" + a);
}
catch(NegativeOutputException e){
System.out.println("Caught >>" + e);
}
}
}
Output::
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at practice6_creating_custom_exception.main(practice6_creating_custom_exception.java:21)
Process finished with exit code 1
It gives you a java. lang.ArrayIndexOutOfBoundsException because you are trying to access a position in an empty array.
parseInt() is not used for taking inputs in such a case you need to use Scanner
For your case, you need first take input (by using Scanner) and then assign it to an integer variable, directly parsing the argument array will not provide the input.
Scanner sc = new Scanner();
int x = sc.nextInt(); //Scans the next token of the input as an int
parseInt() function -
The parseInt() method parses a value as a string and returns the first integer.
Source
Scanner Class -
Scanner object holds the address of InputStream object present in the
System class. Input Stream object of system class reads data from the
keyboard which is byte stream/byte form. The Scanner class converts
this read byte into a specific data type.
Source
The parseInt() function cannot read data from the input stream which is byte stream/byte form, hence you cannot directly parse the args[] array and assign it to an integer variable as it is empty since it is not yet scanned.
If you are looking for different ways of taking input in Java then here they are:
Using Buffer Reader Class,
Using Scanner Class,
Using Console Class,
Using Command Line Argument,
Source
Most probably you are simply not passing any arguments.
One way to pass arguments to the main method in Java is with the command to run the application in terminal. You can simply add the arguments after the java command to run the application separating them with a space. If you want the user to input the data, then you should use Scanner instead.
In your case, navigate to the folder where your java file sits and run the following:
java practice6_creating_custom_exception 0 1
In this example, 0 and 1 are the arguments you are passing.
If you are using an IDE then this can usually be done in the run configurations.
Side note, you might need to compile the application before running it and the command for that is the following:
javac practice6_creating_custom_exception.java
I'm trying to progress displaying a file line by line with an Enter key, but the if statement that I try doesn't seem to work. If I disregard the if statement, it works, but it feels incomplete because then I'm asking for input and doing nothing with it.
This is what I have:
import java.util.Scanner;
import java.io.*;
public class LineByLine {
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
System.out.println("What is the filename?");
String input = in.nextLine();
BufferedReader buff = new BufferedReader(new FileReader(input));
String sen = buff.readLine();
System.out.println(sen);
Scanner enter = new Scanner(System.in);
while (sen != null){
String output = enter.next();
if (output.equals("")){
System.out.println(sen = buff.readLine());
}
}
}
}
I just don't know why my if statement doesn't work.
The core issue is that you misunderstand Scanner and its default configuration: Out of the box, scanner splits on any amount of whitespace. .next() asks for the next token; a token is the thing that appears in between the whitespace.
Thus, pressing enter 500 times produces zero tokens. After all, tokens are what's in between the separator, and the default separator is 'any amount of whitespace'. Pressing enter a bunch of time is still just you entering the same separator.
The underlying problem is that most people appear to assume that Scanner reads one line at a time. It doesn't do that. At all. But you want it to. So, tell it to! Easy peasy - make scanner do what you already thought it did:
Scanner in = new Scanner(System.in);
in.useDelimiter("\\R"); // a single enter press is now the separator.
You should also stop using nextLine on scanners. nextLine and any other next call do not mix. The easiest way to solve this problem is to only ever use nextLine and nothing else, or, never use nextLine. With the above setup, .next() gets you a token which is an entire line - thus, no need for nextLine, which is good news, as nextLine is broken (it does what the spec says it should, but what it does is counterintuitive. We can debate semantics on whether 'broken' is a fair description of it. Point is, it doesn't do what you think it does).
Also, while you're at it, don't make multiple scanners. And, to improve this code, resources must be properly closed. You're not doing that. Let's use try-with, that's what it is for.
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
in.useDelimiter("\\R");
System.out.println("What is the filename?");
String input = in.next();
try (BufferedReader buff = new BufferedReader(new FileReader(input))) {
String sen = buff.readLine();
System.out.println(sen);
while (sen != null){
enter.next(); // why does it matter _what_ they entered?
// as long as they pressed it, we're good, right? Just ignore what it returns.
System.out.println(sen = buff.readLine());
}
}
}
I just started using Java, so sorry if I ask some very simple questions. I basically have to get the user to continuously integers, and once they enter a negative number, the loop will exit. The code I have written so far does not seem to be able to write the input I get from the user to the file I created, morescores. When I try opening the file or calling it from the main method, it's blank. I've tried searching it up on google, youtube, and on stackoverflow but nothing seems to be working. I"ll appreciate any help I can get :)
package bufferedreader;
import java.io.*;
import java.util.Scanner;
public class BufferedReader {
/**
* #param args the command line arguments
* #throws java.io.IOException
*/
public static void main(String[] args) throws IOException {
writeToFile("morescores");
processFile("morescores");
}
public static void writeToFile (String filename) throws IOException {
BufferedWriter outputWriter = new BufferedWriter (new FileWriter ("morescores.txt"));
int score = 1;
while (true) {
Scanner reader = new Scanner(System.in);
System.out.print ("Enter a number: ");
score = reader.nextInt();
if (score < 0) {
break;
} else {
outputWriter.write(score);
outputWriter.newLine();
}
}
outputWriter.flush();
outputWriter.close();
}
public static void processFile2 (String filename) throws IOException {
java.io.BufferedReader inputReader = new java.io.BufferedReader(new InputStreamReader (new FileInputStream ("morescores.txt")));
String line;
while ((line = inputReader.readLine()) != null) {
System.out.println (line);
}
inputReader.close();
}
}
UPDATE: I fixed the problem haha turns out I was trying to print an integer when it could only be a string. I actually have a followup question, I also need to find the average of all the numbers the user inputs. How would I do that? How can I write a code so that the program knows how many times the user inputs a value I actually have a followup question, I also need to find the average of all the numbers the user inputs. How would I do that? How can I write a code so that the program knows how many times the user inputs a value
Convert your int to a String before writing to your file so
outputWriter.write(score);
would be:
outputWriter.write(String.valueOf(score));
if you are wondering why it has to be converted first look at the doc:
https://docs.oracle.com/javase/7/docs/api/java/io/Writer.html#write(int)
you'll see that it doesn't write the int but the character represented by the int
If you pass int value to the write method of BufferedWriter class, then it will be consider as character instead of number, therefore with the current code you have written whatever positive number you are providing will get converted to valid char value and then it will be written into the file.
In order to achieve what you are asking for you need to convert your int value to string before writing it to file and to do that you can use any of the below methods :
String.valueOf(score)
Integer.toString(score)
public class Pack1 {
public static void main(String ar[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("enter the character");
char c=(char)br.read();
System.out.println(c);
System.out.println("enter the integer");
long l=Integer.parseInt(br.readLine());
System.out.println("long l="+l);
System.out.println(c);
}
}
Let's say the user types X and presses Enter on the first question, then types 123 and presses Enter on the second question, that would mean that the input stream contains the following characters:
X <CR> 1 2 3 <CR>
When you call read(), you only read the X. When you then call readLine(), you read the <CR> and get a blank string back.
The 1 2 3 <CR> is still sitting unread in the input stream.
Solution: Call readLine() after reading the X to skip past the rest of the line, or use readLine() to read the X as a String, instead of as a char.
FYI: This is the exact same problem people keep having when using Scanner and mixing calls to nextLine() with calls to other nextXxx() methods, like nextInt().
Change this:
long l=Integer.parseInt(br.readLine());
to :
long l=Long.parseLong(br.readLine(), 10);
This is because you are trying to convert the String to Long and not an Integer type.
when i run the code only with //1 - start, the output is ascii value of input character
when i run the code only with //2 - start, the output is the entered string terminated by newline character
when i run the code with both (as shown in below code), only //1 - start executes, readLine() is being considered in a strange way.
when i run the code with both (with //2 - start placed above //1 - start), both the codes executes fine,
Please explain why this strange behavior happens in case 3 but not in case 4.
public class InputBufferedReader {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
//1-start
//read one character
System.out.println("enter input: ");
int b= br.read();
System.out.println(b);
//end
//2-start
//read a string
System.out.println("enter input string: ");
String a = br.readLine();
System.out.println(a);
//end
} catch (IOException e) {
e.printStackTrace();
}
}
}
Your BufferedReader uses the InputStreamReader with System.in. The BufferedReader uses the read() method from InputStreamReader to read the data from the standard input stream System.in. Now lets look into the API for this read() method.
[...] This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.
Blocking means in this context waits for user to input data throu the console confirming with the Enter Key.
With that in mind lets examine your cases.
1. int b= br.read(); Nothing is already typed, so this method blocks until user typed something and then prints the ascci value of first character.
2. String a = br.readLine(); Nothing is already typed, so this method blocks until user typed something and then prints the whole line.
3.
int b= br.read();
Lets image user typed a confirming with Enter Key that means the input is a\n. Now read() reads the first character which is a.
String a = br.readLine();
This read() call will not block and ask for user input because there is unconsumed input left \n. So readLine() will read \n.
4.
String a = br.readLine();
User is asked for input which is confirmed with Enter Key. And the whole line will be read.
int b= br.read();
There are no unconsumed data left, because readLine() already has read the whole line including \n character. So this read() call blocks and user is asked for input.
int read() method attempts to Read Next Character from the Console(or File) and Return its Unicode Value,
As this Method Returns Unicode Value Compulsory at the Time of Printing we- should perform type- Casting.
If there is No Next Character the we will get -1.
String readLine() Method attempts to Read Next Line from Console(or File) and Returns it, if it is available.
If the Next line is Not available, then return null.