I am really new to learning Java and I am trying to change the user input to lowercase (or uppercase). However it isn't work. Any suggestion?
protected String nextMove()
{
System.out.println("Please enter move");
Scanner in = new Scanner(System.in).toUpperCase();
while (!in.hasNext("['a','b','c']"))
{
String move;
System.out.println("That is not a valid guess");
move = in.nextLine();
in.close();
return move;
}
return nextMove();
}
The Scanner is for getting input, not for translating or transforming it, and your code shouldn't even compile since you're calling a Scanner method that doesn't exist. You instead want to transform the String obtained.
You could simply do:
String myLowerCaseInput = in.nextLine().toLowerCase();
Edit: as a side note, I highly doubt that you will want to create the Scanner object in this method, since you should only create one Scanner object based on System.in. If need be, pass that Scanner into this method using a parameter.
protected String nextMove(Scanner in) {
System.out.print("Please enter move: ");
return in.nextLine().toLowerCase();
}
or better...
private static String nextMove(Scanner in) {
String input = "";
do {
System.out.print("Please enter move: ");
input = in.nextLine().trim().toLowerCase();
} while (input.isEmpty() || input.length() != 1 || !"abc".contains(input));
return input;
}
Try to use this:
Scanner in = new Scanner(System.in);
while (!in.hasNext("['a','b','c']")){
String upercase = in.nextLine().toUpperCase();
...
Related
I'm a beginner in Java and the problem that I've run into is I'm not sure how to chain input validation together so that the proper response to the user's incorrect input is given. For example, when the user enters something that's not a letter, the program does tell the user that what they've entered is not a letter, but if I then enter more than one letter, the program doesn't print out the correct response. It's based on whichever mistake the user makes first.
I appreciate all feedback.
String input;
final Pattern alphabet = Pattern.compile("^[A-Za-z]$");
Scanner kb = new Scanner(System.in);
System.out.println("Enter a letter of the alphabet: ");
input = kb.nextLine();
while (!alphabet.matcher(input).matches())
{
System.out.println("That's not a letter, try again.");
input = kb.nextLine();
}
while (input.length() > 1 )
{
System.out.println("Please enter only one letter");
input = kb.nextLine();
}
kb.close();
You can try to do likes this: Make it become check condition in if and get the result
final Pattern alphabet = Pattern.compile("^[A-Za-z]$");
Scanner kb = new Scanner(System.in);
public void drive_main() {
System.out.println("Enter a letter of the alphabet: ");
String input = getInput();
while (input == null) {
input = getInput();
}
}
public String getInput() {
String result;
result = kb.nextLine();
if (!alphabet.matcher(result).matches()) {
System.out.println("That's not a letter, try again.");
return null;
}
if (result.length() > 1) {
System.out.println("Please enter only one letter");
return null;
}
return result;
}
OR you can assign you input to a new class package (input, error, and have an error or not) make it more flexible.
final Pattern alphabet = Pattern.compile("^[A-Za-z]$");
Scanner kb = new Scanner(System.in);
public void drive_main() {
System.out.println("Enter a letter of the alphabet: ");
InputSet input = getInput(kb.nextLine());
while (input.isError) {
System.out.println(input.errorMessage);
input = getInput(kb.nextLine());
}
}
public InputSet getInput(String input) {
InputSet result = new InputSet(input, false, "");
if (!alphabet.matcher(result.input).matches()) {
result.errorMessage = "That's not a letter, try again.";
result.isError = true;
}
if (result.input.length() > 1) {
result.errorMessage = "Please enter only one letter";
result.isError = true;
}
return result;
}
private class InputSet {
String input;
boolean isError;
String errorMessage;
InputSet() {
}
InputSet(String input, boolean isError, String errorMessage) {
this.input = input;
this.isError = isError;
this.errorMessage = errorMessage;
}
}
1st is you should not use the while loop to check the condition.
2nd design your program properly loop > verify error.
You should do more good practical and clean code than you can easily find the error. Try to use less loop as possible it will cause more error and the program memory using
I'm bulding a console application where I am trying to force a user to enter an int as a possible answer to a question otherwise the same question is repeated to the user.Thus, the user cannot move on without entering the proper data type.
below is my sample code.
Scanner scanner = new Scanner(System.in);
int userInput = 0;
do {
AskQuestion();
if(scanner.hasNextInt()) {
userInput = scanner.nextInt();
}
}
while(!scanner.hasNextInt()) ;
While I know this can be done in C#, I'm not exactly sure how to do it in java without getting stuck in an infinite loop. How do I get my code to do what I want to do? Please help!
You can use something like this. It'a a pretty simple flag combined with the use of the Scanner class.
boolean flag = false;
int val = 0;
while(!flag){
System.out.println("Something");
if(sc.hasNext()){
if(sc.hasNextInt()){
val = sc.nextInt();
flag = true;
}
else{
sc.next();
}
}
}
Try this:
Scanner scanner = new Scanner(System.in);
int userInput;
while(true) {
AskQuestion();
if (scanner.hasNextInt()) {
userInput = scanner.nextInt();
break;
}
scanner.next(); // consume non-int token
}
Another alternative which utilizes the Scanner#nextLine() method along with the String#matches() method and a small Regular Expression (RegEx) to ensure that the supplied string does indeed contain all numerical digits:
Scanner scanner = new Scanner(System.in);
String userInput = "";
int desiredINT = 0; // Default value.
while (desiredINT == 0) {
AskQuestion();
userInput = scanner.nextLine();
if (userInput.matches("\\d+")) {
desiredINT = Integer.parseInt(userInput);
if (desiredINT < 1 || desiredINT > 120) {
System.out.println("Invalid Input! The age supplied is not "
+ "likely! Enter a valid Age!");
desiredINT = 0;
}
}
else {
System.out.println("Invalid Input! You must supply an Integer "
+ "value! Try Again...");
}
}
System.out.println("Your age is: --> " + desiredINT);
And the AskQuestion() method:
private void AskQuestion() {
System.out.println("How old are you?");
}
This is nice and short one
Scanner scanner = new Scanner(System.in);
do askQuestion();
while(!scanner.nextLine().trim().matches("[\\d]+"));
Tell me if you like it
Note it just tell you if number was an int , and keeps repeating if not, but doesn't give you that int back , tell me if you need that, i shall find a way
My solution might be a bit bloated, but I hope it's nice and clear what's going on. Please do let me know how it can be simplified!
import java.util.Scanner; // Import the Scanner class
class Main {public static void main(String[] args) {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
String unit;
// unit selector
while (true) {
System.out.println("Did you measure ion feet or meters? Type 'meters' or 'feet': ");
String isUnit = myObj.nextLine();
if (isUnit.equals("feet") || (isUnit.equals("meters"))) {
unit = isUnit;
break;
} else {
System.out.println("Please enter either 'meters' or 'feet'.");
}
}
System.out.println("Use selected " + unit);
}
I am trying to write a junit test to test a method that takes multiple user input.
The method takes a person object and sets a rating for them, the first user input is a double value for the rating, the second input is a string with the value "Y" to confirm the change.
I am trying to use ByteArrayInputStream but it is not getting the second input, the error I am getting when i run the test is No line found.
I have identified the problem as I am using different methods to validate user input I have to create a new scanner each time so the second line is not being accepted
Is there a way to set the Scanner again for the second input?
This is my test code
Person p = new Person();
double input1 = 54.3;
String input2 = "Y";
String simulatedUserInput = input1 +
System.getProperty("line.separator")
+ input2 + System.getProperty("line.separator");
System.setIn(new ByteArrayInputStream(simulatedUserInput.getBytes(StandardCharsets.UTF_8)));
addRating(p);
assertEquals(54.3, p.getMyRating(),0);
The method for adding the rating looks like this
public static void addRating(Person p)
{
double rating = Validation.validateRating("Please enter a rating for " + p.getName()); // validate input of double
boolean confirmed = Validation.validateYesNo("Are you sure you wish to set " + p.getName() + "'s rating to " + rating + " Y/N");// confirm yes no
if (confirmed)
{
p.setMyRating(rating);
}
}
Then I have a validation class to ensure correct user input,
This is for the rating
public static double validateRating(String str)
{
Scanner in = new Scanner(System.in);
double d = 0;
boolean valid = false;
while (!valid)
{
System.out.println(str);
if (!in.hasNextDouble())
{
System.out.println("Not a valid number");
in.nextLine();
} else
{
d = in.nextDouble();
if(d>=0 && d<=100)
{
valid = true;
}
else
{
System.out.println("Rating must be between 0 and 100");
}
}
}
return d;
}
this is for confirming Y/N input
public static boolean validateYesNo(String str)
{
Scanner in = new Scanner(System.in);
boolean YesNo = false;
boolean valid = false;
while (!valid)
{
System.out.println(str);
String choice = in.next();
if (choice.equalsIgnoreCase("Y"))
{
valid = true;
YesNo = true;
} else if (choice.equalsIgnoreCase("N"))
{
valid = true;
YesNo = false;
} else
{
System.out.println("Invalid input");
}
}
return YesNo;
}
You get unit testing wrong. You don't write your production code first; to later discover: this is really hard to test.
Instead: right from the beginning, you strive to write code that is as easy as possible. Ideally, you even write testcases before you write production code.
Because that helps you discovering the abstractions you need. In your case: in order to validate input values within your Person class, it should not be important, where those values are coming from.
In other words: you do not never ne jamais put System.in read calls into your production classes. You might have a test main method that reads values from the console; but you always pass such values into a method as parameter. If at all, you pass an instance Reader into your classes. You do not turn to System.in inside your methods!
So I just started learning Java, its literally like my 1st day and I wanted to try to make a coinflip game. I already know a decent amount of Javascript and so i was trying to apply that knowledge to java. So everything has been working so far except one thing: Prompting a user for a choice. So read online that i have to import a scanner so i did that as you can see from my code. I also tried some code where you can have the user import a string but you can see a bit later in my program i change the variable userChoice into a number. So basically i just need help with this. If there is some way to have a variable type that can store both numbers or strings that would be best. But im tottaly open to other ways of doing this! Thanks in advanced! Here is the code:
package test;
import java.util.Scanner;
public class testclass {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("hi");
int bob;
bob = (int) Math.floor(Math.random()*2);
System.out.println(bob);
System.out.println("Enter heads or tails?");
System.out.println("You entered "+ userChoice);
if (bob == 0) {
System.out.println("Computer flipped heads");
}
else {
System.out.println("Computer flipped tails");
}
if(userChoice == "Heads") {
userChoice = 0;
}
else {
userChoice = 1;
}
if (userChoice == bob) {
System.out.println("You win!");
}
else {
System.out.println("Sorry you lost!")
}
}
}
Use a scanner, as you said:
Scanner in = new Scanner(System.in);
Then, prompt the user to enter something in:
String userChoice = in.nextLine();
Also, when you compared strings:
if(userChoice == "Heads") {...
that's bad to do for none-primitive objects. It's best to only use the == to compare values that are ints or enums. If you compare a String like this, it won't work, because it's checking if the objects are the same. Instead, compare like this:
if(userChoice.equals("Heads")) {...
Also, to convert to an int (NOTE: You can't convert one type of object to another that aren't related in any way! You'll have to create a new object if you're wanting to do that), do this:
int myInt = Integer.parseInt(myString); // NOTE: Can throw NumberFormatException if non-number character is found.
So your program should look somewhat like:
package test;
import java.util.Scanner;
public class testclass {
public static void main(String[] args) {
//System.out.println("hi");
Scanner in = new Scanner(System.in);
int bob;
int userChoice;
String input;
bob = (int) Math.floor(Math.random()*2);
System.out.println(bob);
System.out.println("Enter heads or tails?");
input = in.nextLine(); // waits for user to press enter.
System.out.println("You entered "+ input);
if (bob == 0) {
System.out.println("Computer flipped heads");
}
else {
System.out.println("Computer flipped tails");
}
if(input.equals("Heads")) {
userChoice = 0;
}
else {
userChoice = 1;
}
if (userChoice == bob) {
System.out.println("You win!");
}
else {
System.out.println("Sorry you lost!");
}
in.close(); // IMPORTANT to prevent memory leaks
}
}
You've already imported the Scanner class so you can now create a variable of the type Scanner for taking inputs.
Scanner in = new Scanner();
userChoice = in.nextLine();
nextLine() can be used to input a character or a string from the user.
To convert the string into a integer, You can assign the integer value to the string in the following way.
if(userChoice == "Heads") {
userChoice = "" + 0;
}
else {
userChoice = "" + 1;
}
"String" datatype in Java can hold both numbers and strings (as you asked). You can get user input using Scanner utility as below:
Scanner input = new Scanner();
userChoice = input.nextLine(); // if it is a string
//userChoice = input.nextInt(); // if it's integer choice
If your string is an integer then you can also parse it to get its integer value. For parsing:
int value = Integer.parseInt(userChoice);
Also for comparing String values you should use "equals" function rather than "==".
if(userChoice.equals("Heads")){...} //rather than if(userChoice == "Heads"){...}
Having imported java.util.Scanner, to get input from the user as a String, create a Scanner object that parameterizes System.in and assign userChoice the value of nextLine() invoked by the Scanner object:
Scanner input = new Scanner(System.in);
String userChoice = input.nextLine();
A few things about your code. The relational operator, ==, is used for comparing primitive data - not objects. Use string1.equals(string2) to see if two strings are equal.
Also, bob = (int) Math.floor(Math.random()*2); is really bob = (int)(Math.random() * 2);
because casting a double as an integer truncates the double to the highest integer less than or equal to it.
It might help you to get the ideas.
public static void main(String[] args) {
Random rd = new Random();
//Enter 1 0R 0
int bob = rd.nextInt(2);
String userChoice;
Scanner sc = new Scanner(System.in);
System.out.println("Please enter a number");
userChoice = sc.nextLine();
System.out.println("You entered " + userChoice + " and bob is " + bob);
int uc = Integer.parseInt(userChoice);
if (uc == bob) {
System.out.println("Hehe");
} else {
System.out.println("Sorry");
}
}
I'm working on a Chat Bot project, and I'm almost done, other than the fact that whenever I enter an input, it returns multiple outputs depending on the length of the input X.
Here is the source code:
import java.util.*;
public class ChatBot
{
public static String getResponse(String value)
{
Scanner input = new Scanner (System.in);
String X = longestWord(value);
if (value.contains("you"))
{
return "I'm not important. Let's talk about you instead.";
}
else if (X.length() <= 3)
{
return "Maybe we should move on. Is there anything else you would like to talk about?";
}
else if (X.length() == 4)
{
return "Tell me more about " + X;
}
else if (X.length() == 5)
{
return "Why do you think " + X + " is important?";
}
return "Now we are getting somewhere. How does " + X + " affect you the most?";
}
private static String longestWord(String value){
Scanner input = new Scanner (value);
String longest = new String();
"".equals(longest);
while (input.hasNext())
{
String temp = input.next();
if(temp.length() > longest.length())
{
longest = temp;
}
}
return longest;
}
}
This is for testing the Chat Bot:
import java.util.Scanner;
public class Test {
public static void main (String [ ] args)
{
Scanner input = new Scanner (System.in);
ChatBot e = new ChatBot();
String prompt = "What would you like to talk about?";
System.out.println(prompt);
String userInput;
userInput = input.next();
while (!userInput.equals("Goodbye"))
{
System.out.println(e.getResponse(userInput));
userInput = input.next();
}
}
}
I am also trying to modify the Bot so it counts the number of times it has responded; and also modify it so it randomly returns a random response depending on the length of the input. Any help will be much appreciated. Thank You!
You are using the Scanner.next method which only returns the next word in the string. So if you input a string with multiple words, your bot will respond to each of them.
You can use Scanner.nextLine() to get the entire input string, instead of only 1 word.
To count the number of times your bot has responded, you can create a field in the bot class:
private int responseCount = 0;
Then if you change yout getResponse method from a static method to an instance method, you can update this value from this method:
public String getResponse(String value)
{
String X = longestWord(value); //Your longestWord should also not be static.
this.responseCount++;
if (value.contains("you"))
{
...
Regarding counting the responses, just modify your main method:
import java.util.Scanner;
public class Test {
public static void main (String [ ] args)
{
int numberOfResponses = 1;
Scanner input = new Scanner (System.in);
ChatBot e = new ChatBot();
String prompt = "What would you like to talk about?";
System.out.println(prompt);
String userInput;
userInput = input.next();
while (!userInput.equals("Goodbye"))
{
System.out.println(e.getResponse(userInput));
userInput = input.nextLine();
numberOfResponses++;
}
input.close();
System.out.println(numberOfResponses);
}
}
If I have the time I will edit my post in a few minutes to check your problem regarding the double appearences of a response. You also forgot to close the Scanner.
EDIT: It actually happens because scanner has as a default the delimiter set to be on whitespace. so if you input a text with a whitespace, the while loop runs twice for one user input. Just use the nextLine() command.
Why is this code:
Scanner input = new Scanner (System.in);
In your getResponse method? Its not used at all. Take a closer look at your methods as they are holding some strange code.