I am using .contains() to check standard input, but it seems not to work for me. For example even if I put hi there as standard input I get:
hi there
nobody likes to eat peas is true
I am expecting to get in addition:
hi there is true
public static void main(String[]args){
Scanner sc = new Scanner(System.in);
String inp = sc.next();
String fixed = "nobody likes to eat peas";
if (inp.contains("hi there")){
System.out.println(inp + " is " + true);
}
if (fixed.contains(" to eat ")){
System.out.println(fixed + " is " + true);
}
}
My Question is: does standard input not work with the .contains() method even though the standard input should match the input using .contains() or is my code wrong?
Scanners work by treating the input as if it is split into chunks, where in between each chunk (called a 'token') is the delimiter.
Out of the box, 'any sequence of whitespace' is the delimiter. So, inp couldn't possibly contain hi there - after all, if you fed that input straight to the program, the first token is hi. That's all that inp would contain. A second call to next() would then return there.
It sounds like you intend for the scanner to treat entire lines as the chunks, and newline symbols as the delimiter.
All you have to do, is tell scanner about it, and all will be well:
Scanner sc = new Scanner(System.in);
sc.useDelimiter("\r?\n");
// rest of your code as normal
NB: \r?\n is regexp for 'an optional CR followed by a required LF'. This catches both unix/macosx style newlines (\n) as well as windows style newlines (\r\n).
Related
New to programming, so my apologies if this is dumb question.
When utilizing the Scanner class, I fail to see if there is an option for obtaining a single character as input. For example,
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String a = input.nextLine();
}
}
The above code allows me to pull the next line into a string, which can then be validated by using a while or if statement using a.length() != 1 and then stored into a character if needed.
But is there a way to pull a single character instead of utilizing a string and then validating? If not, can someone explain why this is not allowed? I think it may be due to classes or objects vs primitive types, but am unsure.
You can use System.in.read() instead of Scanner
char input = (char) System.in.read();
You can also use Scanner, doing something like:
Scanner scanner = new Scanner(System.in);
char input = scanner.next().charAt(0);
For using Stringinstead of char, you can also to convert to String:
Scanner scanner = new Scanner(System.in);
String input = String.valueOf(input.next().charAt(0));
This is less fancy than other ways, but for a newbie, it'll be easier to understand. On the other hand, I think the problem proposed doesn't need amazing performance.
Set the delimiter so every character is a token:
Scanner input = new Scanner(System.in).useDelimiter("(?<=.)");
String c = input.next(); // one char
The regex (?<=.) is a look behind, which has zero width, that matches after every character.
I started doing the CodeAbbey problems last night, they mentioned using stdIn since some the input data is long so copy/paste is much easier than by hand. I had never used the Scanner before so it looked easy enough. I got it working for single line inputs then I got a problem where the input was:
867955 303061
977729 180367
844485 843725
393481 604154
399571 278744
723807 596408
142116 475355
I assumed that nextLine would read each couple, xxxx yyyyy. I put the code in a while loop based on if nextLine is not empty. It runs, but I get weird output, and only after I hit return a few times.
package com.secryption;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("Input: ");
Scanner scanner = new Scanner(System.in);
String input = "";
while(!(scanner.nextLine().isEmpty())) {
input = input + scanner.nextLine();
}
String[] resultSet = input.split("\\s+");
for(String s : resultSet) {
System.out.println(s);
}
}
}
I thought I might need something after adding scanner.nextLine() to input. I tried a space and that didn't help. I tried a newline and that didn't make it better.
This "should" put all the numbers in a single array, nothing special. What am I missing with scanner?
EDIT: Ok so #Luiggi Mendoza is right. I found this How to terminate Scanner when input is complete? post. So basically it it working, I just expected it to do something.
The problem is here:
while(!(scanner.nextLine().isEmpty())) {
input = input + scanner.nextLine();
}
Scanner#nextLine reads the line and will continue reading. You're reading two lines and not storing the result of the first line read, just reading and storing the results of the second.
Just change the code above to:
StringBuilder sb = new StringBuilder();
while(scanner.hasNextLine()) {
sb.append(scanner.nextLine()).append(" ");
}
hasNext() is an end of file indicator that terminates by combining keys control d on Mac ox and control z on windows pressing enter won't send the right message
to JVM
I have started to learn Java, wrote couple of very easy things, but there is a thing that I don't understand:
public static void main(String[] args) throws java.io.IOException
{
char ch;
do
{
System.out.println("Quess the letter");
ch = (char) System.in.read();
}
while (ch != 'q');
}
Why does the System.out.println prints "Quess the letter" three times after giving a wrong answer. Before giving any answer string is printed only once.
Thanks in advance
Because when you print char and press Enter you produce 3 symbols (on Windows): character, carriage return and line feed:
q\r\n
You can find more details here: http://en.wikipedia.org/wiki/Newline
For your task you may want to use higher level API, e.g. Scanner:
Scanner scanner = new Scanner(System.in);
do {
System.out.println("Guess the letter");
ch = scanner.nextLine().charAt(0);
} while (ch != 'q');
Using System.in directly is probably the wrong thing to do. You'll see that if your character is changed from q to something in Russian, Arabic or Chinese. Reading just one byte is never going to match it. You are just lucky that the bytes read from console in UTF-8 match the character codes for the plain English characters.
The way you are doing it, you are looking at the input as a stream of bytes. And then, as #Sergey Grinev said, you get three characters - the actual character you entered, and the carriage return and line feed that were produce by pressing Enter.
If you want to treat your input as characters, rather than bytes, you should create a BufferedReader or a Scanner backed by System.in. Then you can read a whole line, and it will dispose of the carriage return and linefeed characters for you.
To use a BufferedReader you do something like:
BufferedReader reader = new BufferedReader( InputStreamReader( System.in ) );
And then you can use:
String userInput = reader.readLine();
To use a Scanner, you do something like:
Scanner scanner = new Scanner( System.in );
And then you can use:
String userInput = scanner.nextLine();
In both cases, the result is a String, not a char, so you should be careful - don't compare it using == but using equals(). Or make sure its length is greater than 1 and take its first character using charAt(0).
As has been mentioned, the initial read command takes in 3 characters and holds them in the buffer.
The next time a read command comes around, it first checks the buffer before waiting for a keyboard input. Try entering more than one letter before hitting enter- your method should get called however many characters you entered + 2.
For an even simpler fix:
//add char 'ignore' variable to the char declaration
char ch ignore;
//add this do while loop after the "ch = (char) System.in.read();" line
do{
ignore = (char) System.in.read();
} while (ignore != '\n');
this way 'ignore' will cycle through the buffer until it hits the newline character in the buffer (the last one entered via pressing enter in Windows) leaving you with an fresh buffer when the method is called again.
I am trying to write a string input to a text file using the Scanner object.
The string input is a film name. If the file name has two words, though, the scanner object only takes the first word.
I need it to take both words. Here is my code:-
Scanner new_dvd_info = new Scanner(System.in);
System.out.println("Enter name of new film");`
String film_name = new_dvd_info.next();
Can anybody shed any light please?
Replace new_dvd_info.next() with new_dvd_info.nextLine() to grab the entire line.
Documentation of Scanner.next() method says
Finds and returns the next complete token from this scanner.
A complete token is preceded and followed by input that matches
the delimiter pattern. This method may block while waiting for input
to scan, even if a previous invocation of {#link #hasNext} returned
<code>true</code>.
So it would just pick up until it finds " " as delimiter in your case. You could use next line method on scanner to get whole string new_dvd_info.nextLine() alternatively you could just loop over like:
while(scanner.hasNext) {
//append to string using scanner.next();
}
The problem here is that you are using new_dvd_info.next() which returns the first complete token. If any delimiter such as space is encountered it considers the next word as a separate token.
Scanner sc=new Scanner(System.in);
String s=sc.next();
System.out.println(s);
In the above code if you give the name of the movie as Age of Ultron it will return you just the tokenAge as there is a delimiter after the token age.
In case you want the complete String separated by delimiter you should use
Scanner sc=new Scanner(System.in);
String s=sc.nextLine();
System.out.println(s);
This will give you the desired output i.e. Age of Ultron
This is my code:
Scanner scan = new Scanner(System.in);
String speed_string = scan.nextLine();
String[] string_array = speed_string.split("\\s");
I want my code to handle newlines, such as copy-pasting two or more paragraphs into a single nextLine. Is that possible? As it is currently, it will take in whatever the input until the newline.
It will stop at the newline, as per the API states:
Since this method continues to search through the input looking for a
line separator, it may buffer all of the input searching for the line
to skip if no line separators are present
So no, you cannot paste a big block and expect it to take it at once.
See nextLine method
You can't change the fact that nextLine() returns one line. that's its whole purpose. You can read two lines and combine those two strings, though. Of course that means some knowledge of the file format.
There is no possibility to do that using Scanner class because it can only read line confirmed by 'enter' or newline sign.
But you can also handle concatenating two lines using ArrayUtils.
Scanner scan = new Scanner(System.in);
String speed_string = scan.nextLine();
String speed_string1 = scan.nextLine();
String[] string_array = speed_string.split("\\s");
String[] string_array1 = speed_string.split("\\s");
String[] both = ArrayUtils.addAll(string_array , string_array1 );