I have been searching for this but couldn't find it. I want to get command moves input from user in Java using Scanner. The inputs the user can make are U(up), D(down), L(left), R(right). So for instance if the user writes UDULR (with nothing separating them) then I want to read in the letters separately. I tried like this:
String command;
char command;
Scanner scan = new Scanner(System.in);
System.out.println("Enter commands U(up),D(down),L(left),R(right);
//command = scan.next();
command = scan.next().charAt(0);
if(command == 'U'){
"Do this"
}
else if(command == 'D'){
"Do that"
}
When I use this code it only recognizes the first letter, (in this case I understand that charAt(0) represents the first letter). But how is it possible to get the other inputs? I tried both with String and char.
By default Scanner uses one or more whitespaces as delimiter, which separates tokens, so next returns token representing entire word, not single characters.
If you want next to return single non-whitespace characters then you can set delimiter to
series of whitespaces (\s+ in regex where \ needs to be written as "\\" in String)
or
empty string ""
But since zero OR one or more of X is same as zero or more of X, instead of + which in regex means "one or more occurrences", we can use * which represents "zero or more occurrences". So regex representing our delimiter may look like \s+ (which in String literal needs to be written as "\\s+" since \ needs to be escaped)
Demo:
Scanner scan = new Scanner(System.in);
scan.useDelimiter("\\s*");
System.out.println("Enter commands U(up),D(down),L(left),R(right)");
String command = scan.next();
if (command.equalsIgnoreCase("U")) {
System.out.println("Do this");
} else if (command.equalsIgnoreCase("D")) {
System.out.println("Do that");
} else {
System.out.println("unknown command: "+ command);
}
Based on your comment it looks like you want to handle group of commands passed as one word like UDULR which should move up, down, up, left and finally right. In that case you could organize your code like:
private void moveUp(){
//code for moving up:
System.out.println("moving up");
}
private void moveDown(){
//... similar
}
//rest of moving methods...
Now you can add one more method which will let chose which method to use based on char we pass to it:
public void move(char dirrection){
switch(dirrection){
case 'U' : moveUp(); break;
case 'D' : moveDown(); break;
case 'L' : moveLeft(); break;
case 'R' : moveRight(); break;
default: System.out.println("can't move in dirrection: "+dirrection);
}
}
Now in your code you should be able to use something like:
System.out.println("Enter commands U(up),D(down),L(left),R(right)");
String command = scan.next();
for (char directionCommand : command.toCharArray()){
move(directionCommand);
}
You need to save the result of next() in a variable; then you can use it to get any character in it in any order you want.
Related
Example output
file1.txt contents
I have to do a project to determine whether user input is a Palindrome (same letters forwards as backwards). I must create a menu and the user selects whether to input through the console or through a file. I had no issue with reading from the console. I am having trouble producing the correct output through reading Files however.
For a file to be a palindrome, the whole file must be able to be read forwards and backwards and be equal. Then the file contents must be printed and labeled as a Palindrome. I am able to determine if a string is a palindrome within the file, but not the whole file itself. I tried to use .hasNextLine() and compare the lines, but the output is not exactly what is desired.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.InputMismatchException;
import java.util.Scanner;
public class PalindromeMachine { //begin class
public static void main(String[] args) { //begin main
boolean choice1 = false;
boolean choice2 = false;
boolean choice3 = false;
while (choice3 == false) {
//create a menu
System.out.println("Welcome to the Palindrome Machine!");
for (int i = 0; i < 35; i++) {
System.out.print("-");
}
System.out.printf("\n1. Read one word from the keyboard");
System.out.printf("\n2. Read one or more words from a file");
System.out.printf("\n3. Exit");
System.out.printf("\nEnter your selection: ");
//gather user input
Scanner user = new Scanner(System.in);
try {
int num = user.nextInt();
if (num > 3 || num < 1) {
System.out.println("Invalid menu option");
}
if (num == 1) {
choice1 = true;
}
if (num == 2) {
choice2 = true;
}
if (num == 3) {
choice3 = true;
}
} catch (InputMismatchException e) {
System.out.println("Invalid menu option");
}
//based on user selection, read in the word or read in lines from a file
while (choice1 == true) {
System.out.printf("Enter the word you would like to check: ");
String checkThis = user.next();
int front = 0;
int back = checkThis.length() - 1;
while (front < back) {
if (checkThis.charAt(front) != checkThis.charAt(back)) {
choice1 = false;
System.out.printf("%s: this word is not a palindrome\n\n", checkThis);
}
front++;
back--;
}
if (choice1 == true) {
System.out.printf("%s: this word is a palindrome\n\n", checkThis);
choice1 = false;
}
} //end while for choice 1
//read from file and determine if palindrome
while (choice2 == true) {
System.out.printf("Enter the file you would like to check: ");
String name;
name = user.nextLine();
try {
File pali = new File(name);
Scanner userRead = new Scanner(pali);
while (userRead.hasNextLine()) {
String checkThis = userRead.nextLine();
//palindrome info
int front = 0;
int back = checkThis.length() - 1;
while (front < back) { //palindrome
if (checkThis.charAt(front) != checkThis.charAt(back)) {
choice2 = false;
System.out.printf("\n%s: this file is not a palindrome",
checkThis);
}
front++;
back--;
} //end palindrome
if (choice2 == true && userRead.hasNextLine() != false) {
System.out.printf(checkThis
+ ": this file is a palindrome\n");
choice2 = false;
} else {
System.out.println("");
System.out.printf(checkThis);
}
} //end of while the file has text
} catch (FileNotFoundException e) {
System.out.printf("\nInvalid file");
}
} // end choice 2
//loop until the user exits + catch inputmismatch
} // end while it loop until exit
} //end main
} //end class
If your intent is to read the entire file and then check if the entire contents are a palindrome or not, then lines in general are a bit of a complicated mess.
Is:
Hello, there!
!ereht ,olleH
A palindromic file? Note that it ends in a newline, so if you attempt to compare byte-for-byte, it's not. If the intent is that it is supposed to 'count', then presumably you'd first trim (lop any whitespace off of the front and back of the entire thing) and then compare byte-for-byte?
If the file's encoding involves characters smearing out over bytes (common - UTF_8, the most common encoding, can do that for any character that isn't simple ASCII), byte-for-byte fails immediately, so I guess character-by-character? Java's 'character' is actually part of surrogate pairs, so symbols from the higher unicode planes, such as emoji, will thus immediately cause trouble (as the emoji is two characters, and therefore won't be the same backwards and forwards). Just go with 'eh, whatever, no files will contain emoji'? Or try to compare codepoints instead?
What about commas, capitals, and other symbol characters? Is this:
Hello, there!
Ereht, olleh!
supposed to 'count'? If you look at Just the actually letters and forget about casing, it is. But a char-by-char comparison will obviously fail. Before you say: That's not palindromic, the usual "A man, a plan, a canal, Panama!" requires that you disregard non-letters and disregard casing.
In any case, it all starts with reading the entire file as a string; Scanner is designed to read tokens (tokens are the things in between the separator), and it has some ugly misplaced baggage in the form of the nextLine() method that you probably shouldn't be using. In any case, it can't read the entire file in one go which makes this vastly more complicated than it needs to be, so step 1 is do not use it.
There's the new file API which is great for this:
import java.nio.file.*;
Path p = Paths.get(fileName);
String contents = Files.readString(p);
That will read the entire contents. We can then remove everything that isn't a letter from it:
contents.toLowerCase().replaceAll("[^a-z]", "");
That thing is a 'regular expression' which is a mini language for text manipulation. [^...] is 'match any character that isn't mentioned here', and a-z is naturally, everything from a to z. In other words, that says: Take the input, lowercase everything, then replace all non-letters with blank, thus giving you only the letters. I turns "A man, a plan, a canal, Panama!" into "amanaplanacanalpanama".
It even gets rid of newlines entirely.
Now you can use the principle at work in your code (start from the beginning and end, fetch the characters there, compare them. If not equal - it is not a palindrome. If equal, increment your 'front pointer', decrement your 'back pointer', and keep going with the comparisons until your pointers are identical, then it is a palindrome.
Scanner has only two uses:
Keyboard input. In which case you should never use .nextLine() (nextLine is broken. It does what the javadoc says it does, which not what anyone expects, hence, do not use it for this) - and always call .useDelimiter("\\R") immediately after making the scanner. This configures it the way you'd expect. Use .nextX() calls to fetch info. next() for strings .nextInt() for integers, etc. All next calls will read entire lines.
Tokenizing inputs. This is only useful if the input is defined in terms of tokens separated by separators. Only a few formats follow that kinda rule. Even your usual 'CSV' files don't, not really - you need custom CSV parsers for that.
"Read an entire file to see if it is palindromic" fits neither use.
I'm having an issue with using the substring method to find a specific character in a string variable. Currently I have a for loop setup to loop over the length of a string variable named name. I then have my substring method inside of my if statement to find my specific character, in this case it is a ".".
I'm not able to get this to work and would appreciate any help. Thank you.
System.out.println("\nEnter name: ");
String name = in.nextLine();
int length = name.length();
for (int x = 0; x < length; x++) {
if(name.substring(x,x+1).equals(".")) {
System.out.println("Error! - name can not contain (.) values\n"
+ "***************************************************");
System.out.println("\nWould you like to capture another name?" +
"\nEnter (1) to continue or any other key to exit");
String opt1 = in.nextLine();
// If statement to run application from the start
if (opt1.equals("1")) {
System.out.println("menu launch");
}
else { System.exit(0); }
}
else { break; }
}
Don't reinvent the wheel. Instead of looping over the characters of the string, you could just use the contains method:
if (name.contains(".")) {
// logic comes here...
While Mureinik is correct on the best way to accomplish your goal, the reason your function does not work is because of your else { break; } statement.
break terminates the loop so unless the very first character is a ., then the loop will exit immediately after the first iteration. When you want to increment the loop, the correct keyword is continue although it is unnecessary in this case because all of the logic is housed inside of the if statement. Since there is no other logic to avoid, you should delete the else statement.
My code is telling me that the case 'A+' is an invalid character statement, but I need to be able to have case A+, A, A- and so on. What I'm wondering is: can I not have + or - inside the case value at all? and if so, is there any other way to identify what the user inputs into the console. I haven't been able to find an answer browsing around. Help is appreciated!
import java.util.Scanner;
public class GradeAdvice {
public static void main(String[] args) {
// User will input grade and program will give advice corresponding
// to that grade
// Prompt use for their grade
System.out.println("What was your grade on the midterm?");
char midtermGrade;
// Create an input object
Scanner input = new Scanner(System.in);
midtermGrade = input.next().charAt(0);
// Determine which advice to give based on grade
switch (midtermGrade)
{
case 'A+' :
case 'a+' : System.out.println("Continue doing what you have been doing, ask questions");
break;
default: System.out.println("This grade is invalid.");
break;
}
// Close input
input.close();
}
}
Character literals in Java identify one character, not multiple characters, within single-quotes. For multiple characters, you must use a String, delimited by double-quote characters.
In Java 7+, you can use Strings as case labels, e.g.
case "A+":
But you are only using the first character of input. Change
char midtermGrade;
midtermGrade = input.next().charAt(0);
to
String midtermGrade;
midtermGrade = input.next();
A char can hold a single character. Instead, you could just use a String:
String midtermGrade;
// Create an input object
Scanner input = new Scanner(System.in);
midtermGrade = input.next();
// Determine which advice to give based on grade
switch (midtermGrade)
{
// Note that strings are denoted by "s, not 's.
case "A+" :
case "a+" : System.out.println("Continue doing what you have been doing, ask questions");
break;
default: System.out.println("This grade is invalid.");
break;
}
Use String, and normalize the case
switch( input.next().toUpperCase() )
{
case "A+" :
...
default :
...
}
"A+", double quotes for string, single quote for character.
This is because you are using a character instead of a string. A character is exactly what it says, one character. A+ is two characters A and +. Use double quotes (") for string literals. For example:
'A' \\ This is a character
"A" \\ This is a string
"A+" is not char , it is string define it as string .
A+ is a string, not a character. You could've done this in C# (using " rather than '), but not in Java, nor most other languages. Simplest way out for you is probably to convert the switch into a series of 'if' statements.
I have a quick question about an assignment which I have. I want to make a sort of a calculator which will read the input from user, use an if-else-loop to figure out what to do with it and then print the corresponding result.
So if the user inputs: 4 * 5, I want the program to check for two ints, and with a inChar check the type of calculation needed, then an if-else-loop which will do the rest (I know how to write this part) but I need some help on how to write the scanner-sentences where it checks for the different types of input from one line. Hope you understood what I meant.
The part of code which I already have:
Scanner input = new Scanner(System.in);
int a,b;
char c;
double sum;
System.out.println("Velkommen til en helt enkel kalkulator!");
System.out.println("Vennligst tast inn regnestykket, paa formen: tall, regneart, tall med mellomrom imellom hver input: ");
String svar=input.nextLine();
if(c='*'){
sum=a*b;
}else if(c='/'){
sum=a/b;
}else if(c='+'){
sum=a+b;
}else if(c='-'){
sum=a-b;
}else{
System.out.println("Regnearten var ikke forstaaelig. Programmet termineres.");
}
Read your input line by line and parse it after that using either String.split() or Pattern. To read lines use either Scanner or System.in wrapped with BufferedReader
I love regular expressions! So lets use one: (\d+)\s*([*/+-])\s*(\d+)
Broken down:
\d+ = One or more digits
\s* = "Space" zero or more times
[*/+-] = One of *, /, +, or -
The parentheses "capture" the matched elements, so you can access them later. In java, use Matcher.group(int), like shown in the fragment below:
//Do this only once in your program
Pattern calcPattern = Pattern.compile("(\\d+)\\s*([*/+-])\\s*(\\d+)");
//Do this in your loop
Matcher m = calcPattern.matcher(input.nextLine());
if (m.matches()) {
a = Integer.parseInt(m.group(1)); //Get the first group (first set of digits)
c = m.group(2); //Get the second group (operator)
b = Integer.parseInt(m.group(3)); //Get the third group (second set of digits)
//do stuff with a, b, and c
} else {
System.out.println("Please enter a valid expression!");
}
As you progress in skill, the regular expression is easily extendable - replace (\d+) with (\d+(?:.?\d+)?) to accept numbers with decimals, for instance. Play around with an online regexp tester here: http://rubular.com/r/8VibLUpxqP
(Quick note: the double backslashes in the regular expression in the java code are necessary because you can't write a single backslash in a string - http://docs.oracle.com/javase/tutorial/java/data/characters.html)
So I'm having a problem doing an assignment for my java class. The purpose is to create a program that uses a switch statement to convert letters from a string to their phonetics. i.e, A or a becomes Alpha.
The problem I'm having is the switch statement stops reading at the first whitespace in the string. How do i get it to continue reading the string without stopping at whitespaces
(i.e " ")?
Basically user inputs a string "Hi Hi" the output should be "Hotel Indiana Hotel Indiana"
The problem I'm having is it only gives "Hotel Indiana" stopping at the first whitespace i think at least.
This is the code i have so far:(I cut out most of the letters/numbers to save space and kept what i thought was most important for answering the question.)
import java.util.*;
public class SwitchStatement {
/**
* #param args
*/
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.println ("Enter a message: ");
String message = keyboard.next();
for(int i = 0 ; i < message.length(); i++)
switch(message.charAt(i)) {
case 'a':
case 'A':
System.out.print("Alpha");
break;
case 'b':
case 'B':
System.out.print("Bravo");
break;
case ' ':
System.out.print(" ");
break;
default:
System.out.print(message.charAt(i));
break;
}
}
}
Thanks in advance for the help.
String message = keyboard.next(); reads one word at the time of call separated by space (" ").
Use String message = keyboard.nextLine(); to read the whole line including spaces within.
You should use nextLine. If you use next() deliminator comes in to picture which is space char. So eventually you end up reading only one token not full string.
String message = keyboard.nextLine();
e.g For below string
A a B b
keyboard.next()---> will return you A if you again call then B and so on
keyboard.nextLine()-->will return you whole line ie. A a B b which you want