I cant get this to work for some reason. I have an app that reads transactions, when an empty line in entered it needs to print out some stuff.
int transationCount = 0;
while(sc.hasNext())
{
String trans = sc.next();
String mode = trans.substring(0, 1);
Double amount = Double.valueOf(trans.substring(1));
if(mode.equals("C"))
{
c.charge(amount);
ps.println(c.getBalance());
transationCount = transationCount + 1;
}
else if(mode.equals("P"))
{
c.pay(amount);
ps.println(c.getBalance());
transationCount = transationCount + 1;
}
}
ps.println(c.getBalance());
ps.println(transationCount);
I tried
while(sc.hasNext() && !(sc.next().equals("")))
doesnt work. I also tried adding inside the while loop
else if (!(trans.equals("")) {break;}
By default, an empty line will be ignored by the scanner as it is not a valid token.
You could manually check if the line is empty:
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
while(true) {
String line = sc.nextLine();
if (line.isEmpty()) {
System.out.println("Empty line entered");
} else {
System.out.println("received line: " + line);
String[] tokens = line.split("\\s+");
System.out.println("tokens: " + Arrays.toString(tokens));
}
}
}
Your Scanner is using the default delimiter (a whitespace) to tokenize the input.
This means that tokens are words, regardless of the lines they are in.
some
word
only returns two tokens, exactly as
some word
What you really need is to get lines separately, in order to tell which line is empty, and which line contain something. In order to do that, use new line as a separator:
Scanner.useDelimiter("\\n");
Or you might as well use BufferedReader, see BufferedReader.readLine()
Please note that two words on the same line will now be contained in the same trans string. You can use the String.split method to get each word separately.
So then how would I escape the while loop if an empty line is entered? Is there another way? – Infodayne
you can use label over/above your while loop, and break it when emptyLine is encountered
or alternatively you can use
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
while(! line.isEmpty()){
}
line.isEmpty() returns true when line is empty,So condition to enter while loop will become false as now inside while loop we have(! (true)) which equals to (false) therefore while loop will not execute.
Related
I have to convert an infix operation to a postfix one, however the infix operation must be inputted as one character per line. So instead of inputting something like this: 3-2, you would need to input something like this:
3
-
2
I had an idea of using =='\n' to determine whether the inputted character is a next line function so that would determine the end of the equation, but it doesn't work. I tried replacing it with a different character such as =='e', and that works perfectly. What can I do to fix this?
String string = "";
Scanner input = new Scanner(System.in);
boolean flag = true;
while (flag==true)
{
char charIn = input.next().charAt(0);
string = string + charIn;
if (charIn=='e') //inputting 'e' gives me my desired result
{
flag = false;
}
}
//code that passes string to InfixToPostfix method and prints out the answer. this part works fine
You did not specify that this was a school assignment or that you had certain restrictions, so this answer is admittedly a shot in the dark.
I would recommend using a StringBuilder within a loop and reading nextLine() instead of simply next(). This allows you to determine if the entry was empty (ie: the enter key was pressed without entering a character).
Also, we should allow the user to enter more than one character anyway (what happens when they try to enter 22 as a number). Abandoning the char type allows for this.
public static void main(String[] args) {
StringBuilder string = new StringBuilder();
Scanner input = new Scanner(System.in);
boolean flag = true;
while (flag) {
// Capture all characters entered, including numbers with multiple digits
String in = input.nextLine();
// If no characters were entered, then the [ENTER] key was pressed
if (in.isEmpty()) {
// User is done adding characters; exit the loop
flag = false;
} else {
// Otherwise, get the text entered and add it to our final string
string.append(in);
}
}
System.out.println("Final String: " + string);
}
Does this meet your needs?
This should do what you want. Reading just the first character has its limitations.
String string = "";
Scanner input = new Scanner(System.in);
boolean flag = true;
while (flag==true)
{
String nextLine = input.nextLine();
char charIn;
if(nextLine.length() > 0) {
charIn = nextLine.charAt(0); //This is bad idea as you can only operate on single digit numbers
System.out.println("charIn = " + charIn);;
string = string + charIn;
}
else
flag = false;
}
I have file with the below data
A,8,43
B,7,42,
C,9,34
I am using the below code to read the data
Scanner input = new Scanner(new File("D:\\test.txt"));
input.useDelimiter(",|\n");
while(input.hasNext()) {
String name = input.next();
int age = input.nextInt();
int height = input.nextInt();
When I am executing the program I am getting InputMisMatch exception,
Please suggest what is mistake.
At end of second line you have , and line separator (I am assuming \n) This means you have empty element between these two delimiters.
So in third iteration
String name = input.next();
int age = input.nextInt();
int height = input.nextInt();
input.next(); is consuming "", which means input.nextInt() will try to consume C.
To solve this problem you can set delimiter to be combination of one or more commas and line separators like
input.useDelimiter("(,|\n)+");
To improve your code even farther instead of \n you can use \\R added in Java 8 (or \r|\n in earlier versions) to handle all line separators, because currently you don't consider \r as delimiter so it can be treated as valid token.
So better solution would be using
input.useDelimiter("(,|\\R)+"); //for readability
or even
input.useDelimiter("[,\r\n]+");
The problem lies at the use of the useDelimiter method. This method accepts a regular expression as a parameter. You can't just say ,|\n to mean "comma or new line". There are rules.
What you should pass in is "[,\\n]+". This means "one or more characters in the following set: [comma, new line character]".
With the regex that you are passing currently, ,|\n, it means that the delimiter should be either , or \n, but not both. So when it encounters the second line:
B,7,42,
this is what happens:
next reads "B"
nextInt reads "7"
nextInt reads "42"
next reads an empty string that is between the "," and the new line.
nextInt now tries to read the next token "C", which it can't.
EXCEPTION!
I would do things differently -- use one Scanner to parse each line of the File and use a 2nd Scanner nested within the while loop to extract tokens or data from the lines obtained from the first Scanner. For example:
String filePath = "D:\\test.txt";
File file = new File(filePath);
// use try-with-resources
try (Scanner input = new Scanner(file)) {
while (input.hasNextLine()) {
String line = input.nextLine();
Scanner lineScanner = new Scanner(line);
lineScanner.useDelimiter("\\s*,\\s*"); // get comma and any surrounding whitespace if present
String name = "";
int age = 0;
int height = 0;
if (lineScanner.hasNext()) {
name = lineScanner.next();
} // else ... throw exception?
if (lineScanner.hasNextInt()) {
age = lineScanner.nextInt();
} // else ... throw exception?
if (lineScanner.hasNextInt()) {
height = lineScanner.nextInt();
} // else ... throw exception?
// use name, age, height here
System.out.printf("%s %s %s%n", name, age, height);
lineScanner.close(); // don't waste resources -- return them
}
} catch (IOException e) {
e.printStackTrace();
}
Language: Java.
Aim:
Boolean Array gridA[] should become true on whatever index is read from input (i.e. if input is "init_start 2 4 5 init_end" then gridA[] indexes 2,4 and 5 should become true). That much I managed to get working but I have two problems:
input:
init_start int int int int int (...) int init_end
for example: init_start 2 6 12 init_end
Problems:
any integer from input that exceeds the value of (instance variable) int L (which determines the index-length of the array) should be ignored, to prevent integers from outside the domain of Array gridA[] from having influence.
Using if(scanner.nextInt != L){} didn't seem to work.
I also need this method, or the body of the method to start when input begins with "init_start" and stop when input ends with "init_end".
How do write code so that it can read both String and integers from the same input?
I meant to do this using
if(scanner.Next=="init_start") followed by
a = scanner.NextInt; which, as I suspected, didn't work.
Attempts at solving:
After googling I tried putting String initialInputStart in a Scanner:
localScanner(initialInputStart);
but I failed to get that working. Other information I found suggested I'd close and reopen the scanner but I need the information to be read from a single line of input so I doubt that will help.
code:
java.util.Arrays.fill(gridA,false);
java.util.Arrays.fill(gridB,false);
String initialInput;
String initialInputStart;
int a;
int i;//only for testing
i = 0;//only for testing
System.out.println("type integers"); //only for testing
while( scanner.hasNextInt() && i<5){ //I can't find a way to make loop stop without missing input so I'm using i temporarily
a = scanner.nextInt();
gridA[a] = true;
System.out.print(a);
System.out.print(gridA[a]+" ");
i++;
}//end while
I wrote a little program which pretty much does what you described as your aim; I read line by line and split each into tokens I further process. The tokens describe what the data means/what state we are in. The actual data is parsed in the default: case in the switch(token) block and branches in behaviour from state to state (which is merely visible here as we only have two states: "init" and "not init", beside the keywords):
public static void main(String[] args) {
int L = 13; // not sure if this is needed
boolean[] gridA = new boolean[L];
Reader source;
/**
* from file:
* source = new FileReader("grid.csv");
*/
/**
* from classpath resource:
* source = new InputStreamReader(MyClass.class.getResourceAsStream("grid.csv"));
*/
/**
* from string:
* source = new StringReader("init_start 2 6 12 init_end");
*/
/**
* from std-in:
* source = new InputStreamReader(System.in);
*/
try(BufferedReader stream = new BufferedReader(source)) {
boolean init = false;
// loop
input_loop:
while(true) {
// read next line
String line = stream.readLine();
if(line == null) {
// end of stream reached
break;
}
if(line.trim().isEmpty()) {
// ignore empty lines
continue;
}
String[] tokens = line.split(" ");
for (String token : tokens) {
switch (token) {
// evaluate keywords
case "init_start":
init = true;
break;
case "init_end":
init = false;
break;
// for input from console
case "exit":
break input_loop;
default:
// parse input, based on state (expand "init" to an enum for more states)
if(init) {
// read init input
int index = Integer.parseInt(token);
if(index >= 0 && index < gridA.length) {
gridA[index] = true;
} else {
throw new RuntimeException("illegal grid index: " + index);
}
} else {
// read undefined input
throw new RuntimeException("unrecognized token: " + token);
}
break;
}
}
}
} catch(IOException ex) {
throw new RuntimeException("an i/o exception has occurred", ex);
}
System.out.println(Arrays.toString(gridA));
}
" How do write code so that it can read both String and integers from the same input?"
do you want to have an Input like this: "123, foo"
if thats the case use:
String input = scanner.nextLine();
String[] parts = input.split(",");//" " to split it at an empty space
String part1 = parts[0]; // 123
int Number = Integer.parseInt(part1) // you could inline it, but i chose this version for better refference
String part2 = parts[1]; //foo
if your Input looks like this "123 or foo"
you have to read the input as String and check the String afterwards if its a Number:
String input = scanner.nextLine();
if (text.contains("[a-zA-Z]+") == false){ //looks if the input does NOT contain any characters
int nummber = Integer.parseInt(input);
} else{
String text = input;
}
afterward you can compare your text:
For the first mentioned case:
if("init_start".equals(parts[1])){ //*
yourMethod();
}
For the other case:
if("init_start".equals(text)){ //*
yourMethod();
}
*Also:
"I meant to do this using if(scanner.Next=="init_start")"
*Very important! To compare Objects, such as String use .equals(). "==" only works on primitive types
Edit: I've read your example. You could go with a combination of my solutions. split the string at space(" ") and check parts[x] if it is an integer. But i wouldnt recommend this method! Why dont you split your input in three parts: init_start would start your function. After that your method would expect an input of Integers like "int int int" after you inserted the Integers your function could automatically stop or wait for the input "init_stop". That seems to me more reasonable. If you want to go with the single line solution you can evaluate the number of your int's by get tingparts[].lenght()-2
use this implementation:
public static void main(String args[]){
try{
Scanner in = new Scanner(System.in);
System.out.println("Enter a line");
String dat = in.readLine();
System.out.println(dat);
}
catch(IOException e){
System.out.println("IO ERROR !!!");
System.exit(-1);
}
}
I'm trying to take in a string input which consists of multiple lines of numbers separated by ',' and ';' .
Example:
1,2;3,4;5,6;
9,8;7,6;
0,1;
;
Code:
ArrayList<Integer> alist = new ArrayList<>();
String delims = ";|\\,";
int i = 0;
Scanner input = new Scanner(System.in);
input.useDelimiter(delims);
while (input.hasNext()) {
alist.add(i, input.nextInt());
System.out.print(i + ' ');
System.out.print(alist.get(i) + '\n');
i++;
}
System.out.print('x');
When I run this in eclipse:
1,2;3,4;5,6; ( <= what i typed in console)
321133123413351436153716 ( <= output)
I'd expect something more like:
0 1
1 2
2 3
3 4
4 5
5 6
x
Why am I getting this sort of output?
One problem is that System.in is basically an infinite stream: hasNext will always return true unless the user enters a special command that closes it.
So you need to have the user enter something that tells you they are done. For example:
while(input.hasNext()) {
System.out.print("Enter an integer or 'end' to finish: ");
String next = input.next();
if("end".equalsIgnoreCase(next)) {
break;
}
int theInt = Integer.parseInt(next);
...
For your program, you might have the input you are trying to parse end with a special character like 1,2;3,4;5,6;end or 1,2;3,4;5,6;# that you check for.
And on these lines:
System.out.print(i + ' ');
System.out.print(alist.get(i) + '\n');
It looks like you are trying to perform String concatenation but since char is a numerical type, it performs addition instead. That is why you get the crazy output. So you need to use String instead of char:
System.out.print(i + " ");
System.out.print(alist.get(i) + "\n");
Or just:
System.out.println(i + " " + alist.get(i));
Edit for comment.
You could, for example, pull the input using nextLine from a Scanner with a default delimiter, then create a second Scanner to scan the line:
Scanner sysIn = new Scanner(System.in);
while(sysIn.hasNextLine()) {
String nextLine = sysIn.nextLine();
if(nextLine.isEmpty()) {
break;
}
Scanner lineIn = new Scanner(nextLine);
lineIn.useDelimiter(";|\\,");
while(lineIn.hasNextInt()) {
int nextInt = lineIn.nextInt();
...
}
}
Since Radiodef has already answered your actual problem(" instead of '), here are a few pointers I think could be helpful for you(This is more of a comment than an answer, but too long for an actual comment):
When you use Scanner, try to match the hasNextX function call to the nextX call. I.e. in your case, use hasNextInt and nextInt. This makes it much less likely that you will get an exception on unexpected input, while also making it easy to end input by just typing another delimiter.
Scanners useDelimiter call returns the Scanner, so it can be chained, as part of the initialisation of the Scanner. I.e. you can just write:
Scanner input = new Scanner(System.in).useDelimiter(";|\\,");
When you add to the end of an ArrayList, you don't need to(and usually should not) specify the index.
int i = 0, i++ is the textbook example of a for loop. Just because your test statement doesn't involve i does not mean you should not use a for loop.
Your code, with the above points addressed becomes as follows:
ArrayList<Integer> alist = new ArrayList<>();
Scanner input = new Scanner(System.in).useDelimiter(";|\\,");
for (int i = 0; input.hasNextInt(); i++) {
alist.add(input.nextInt());
System.out.println(i + " " + alist.get(i));
}
System.out.println('x');
Edit: Just had to mention one of my favorite delimiters for Scanner, since it is so suitable here:
Scanner input = new Scanner(System.in).useDelimiter("\\D");
This will make a Scanner over just numbers, splitting on anything that is not a number. Combined with hasNextInt it also ends input on the first blank line when reading from terminal input.
this is my first post so forgive me if i have posted incorrectly. I have a task that i need to complete but i cant get it to work properly. the compiler that i use is bluej. what i need to do is to use scanner to read a text file and compare a user input to the text file. if the input string compares then it should print out that ""The word is on the text file". Unfortunately i cant get this to work. My code reads the file because it prints out to the console but no comparison it s happening. please have a look at my code and give me some pointers. i have been trying to use .equals():
private boolean searchFromRecord(String recordName, String word) throws IOException
{
// Please write your code after this line
File file = new File(recordName);
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
for(int i = 0; scanner.hasNextLine(); i++){
String compare = scanner.nextLine();
IO.outputln("word#" + i + ":" + compare);
}
scanner.close();
if (scanner.equals(word)){
return true;
} else{
return false;
}
}
return true;
}
this is what i get output in the console:
Input a word: IRON
AA 888
word#0:BULLET
word#1:1
word#2:AE 1688
word#3:CHEERS
word#4:GAMES
word#5:IRON MAN
word#6:WOLF
word#7:Testing
word#8:Wonderful
The word "IRON" is not in the record.
Here are some problems, along with why they are problems & a suggestion on how they could be fixed:
Problem: closing a scanner within the a loop that uses it will cause an exception. Reason: after we go through the loop once, the scanner will be closed. when we loop through again, an error will occur since the loop uses the scanner, which means the scanner should be "open". Possible solution: move scanner.close() to after the while loop.
Problem: we shouldn't return true at the end of this method. Reason: I'm guessing that this method is supposed to return true if the word is found, and false otherwise. Now, the only way to get to this return statement is if our word doesn't exist in the recordFile; it should return false. Possible solution: return false at the end of the method instead.
Problem: the first line in recordFile will never be checked for equality with word Reason: each method call of scanner.nextLine() will return each line from the recordFile as a String once and only once. In your code, it is called once in the beginning of the while loop's body, but not used to compare with word, then after, it is used in the for loop for comparison Possible solution: remove the line: System.out.println(scanner.nextLine());.
Problem: scanner.equals(word) will probably always return false. Reason: scanner is a Scanner, and word is a String, they should never be equal. Possible solution: replace scanner.equals(word) with compare.equals(word)
Problem: word is not actually compared with each compare. Reason: it is outside the for loop. Possible solution: move the if else block into the end of the for loop's body.
I don't think the while loop is really needed. I strongly recommend that the while loop, is removed, but keep the body.
Problem: Moving the if else block into the for loop, and above the scanner.close() means that the scanner.close() will never be run. Reason: once a return statement is executed, the flow of control immediatly exits the method, and returns to where the method was invoked which makes code after return statements useless. Possible solution: instead of returning right away, declare some sort of boolean variable that will store the return value. have the return value be modified throughout the method, then return the variable at the very end, after scaner.close()
There are many many other ways to fix each of these problems other than the ones suggested here.
I hope you find this helpful! :)
your code, refactored to implement the suggested solutions above:
private boolean searchFromRecord(String recordName, String word) throws IOException {
// Please write your code after this line
Boolean wordFound = false; // indicates if word exists in recordFile.
File file = new File(recordName); // file at path "recordName"
Scanner scanner = new Scanner(file); // reads records from "file"
// iterate through the recordFile, to see if "word" already exists
// within recordFile.
for(int i = 0; scanner.hasNextLine(); i++) {
// read the record from the file
String compare = scanner.nextLine();
IO.outputln("word#" + i + ":" + compare);
// compare the record with our word
if (compare.equals(word)){
wordFound = true;
break; // bail out of loop, our work here is done
}
}
// clean up, and return...
scanner.close();
return wordFound;
}
First, scanner is not a String and it will not equal a String. Second, you are dropping lines - scanner.nextLine() gets the next line, and you print it (but don't save it or compare it). I think you wanted something more like this,
// eats and tosses input.
// System.out.println(scanner.nextLine());
String line = scanner.nextLine();
for(int i = 0; scanner.hasNextLine(); i++){
String compare = scanner.nextLine();
IO.outputln("word#" + i + ": " + compare + " to line: " + line);
if (line.contains(compare)){ // "IRON MAN" starts with "IRON", it doesn't equal IRON.
return true;
}
}
scanner.close();
return false; // <-- default.
Another flavor is to read the whole file into a String variable and look for specified String inside the String.
Code:
File file = new File("C:\\Users\\KICK\\Documents\\NetBeansProjects"
+ "\\SearchWordinFile\\src\\searchwordinfile\\words.txt");
String s="";
try(Scanner input = new Scanner(file)){
input.useDelimiter("\\A");
if (input.hasNext()) {
s = input.next();
}
}catch(Exception e){
System.out.println(e);
}
if(s.contains("IRON"))
System.out.println("I found IRON");
}
Output:
I found IRON
My File content
BULLET
1
AE 1688
CHEERS
GAMES
IRON MAN
WOLF
Testing
Wonderful