I'm taking my very first java class. I need to ask for a zip code. I know how to ask for new input if they don't enter 5 digits, but how do I also ask for new input if they enter a non-integer?
Here is what I have:
import java.util.Scanner;
public class AndrewDemographics {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
int zip; // 5 digit zip
System.out.print("Enter your 5 digit zip code: ");
zip = stdIn.nextInt();
while ((zip < 10000) || (zip > 99999)) {
// error message
System.out.println("Invalid Zip Code format.");
System.out.println("");
System.out.println("Enter your 5 digit zip code: ");
zip = stdIn.nextInt();
} //end if zip code is valid
}
}
To support zip codes starting with 0, you need to store the zip code in a String, and then it's easiest to validate it using a regex:
Scanner stdIn = new Scanner(System.in);
String zip;
do {
System.out.print("Enter your 5 digit zip code: ");
zip = stdIn.next();
} while (! zip.matches("[0-9]{5}"));
If you want to print error message, you can do it like this, which uses nextLine() so simply pressing enter will print error message too:
Scanner stdIn = new Scanner(System.in);
String zip;
for (;;) {
System.out.print("Enter your 5 digit zip code: ");
zip = stdIn.nextLine().trim();
if (zip.matches("[0-9]{5}"))
break;
System.out.println("Invalid Zip Code format.");
System.out.println();
}
As the comment suggests, you will need to take into account zip code starting with zero. I guess for that, you'll need to consider the input as a String:
check if the String is 5 characters long (to match the 5 digits)
String does not contain + sign as +1234 would work
check if the String is a valid integer
check if the Integer is positive as -1234 would be still valid
you now have something between 00000 and 99999
In practice
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
String userInput;
int zipCode = -1;
// flag to stop spamming the user
boolean isValid = false;
while (!isValid) {
// ask the user
System.out.print("Enter your 5 digit zip code: ");
userInput = stdIn.next();
// it should be 5 digits so 5 charaters long:
if (userInput.length() == 5 && !userInput.contains("+")) {
try {
zipCode = Integer.parseInt(userInput);
if (zipCode > 0) {
isValid = true;
}
}
catch (NumberFormatException e) {
// do nothing
}
}
System.out.println("Zip code is invalid!");
}
System.out.println("You have selected the zip code: " + zipCode);
}
There is an issue with zip codes with leading zeros in previous. There needs to be a check if both is a number and is 5 characters in length. A zero leading zip would be 4 digits in length if read in as a number type.
Top of my head:
String zip = null;
do {
zip = stdIn.next();
try {
Integer.parseInt(zip); // this will throw exception if not a number
} catch (NumberFormatException e) {
continue; // this will start the next loop iteration if not a number
}
} while (zip.length() != 5); // this will start the next iteration if not 5 characters
I took the input as a String using nextLine() rather than an int because it accounts for zip codes starting with 0, and a zip code, although written numerically, isn't really a numerical value. I felt that the easiest way to structure the if/else statements determining if the zip code was valid was to use return statements that would break out of the checks at the return, so I wrote a method that would check for the validity of the zip code:
public static boolean checkValidZip(String zip) {
if (zip.length() != 5) { //invalid if not 5 chars long
return false;
}
for (int i=0; i<zip.length(); i++) { //invalid if not all digits
if (!Character.isDigit(zip.charAt(i))) {
return false;
}
}
return true; //valid if 5 digits
}
The main method then, looks like this:
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
String zip = ""; //5 digit zip
boolean valid = false;
boolean allNums = true;
while (!valid) {
System.out.print("Enter your 5 digit zip code: ");
zip = stdIn.nextLine();
valid = checkValidZip(zip);
if (!valid) {
System.out.println("Invalid Zip Code format.");
System.out.println("");
}
}
//end if zip code valid
}
Related
New to java. I need to ask the user the number of strings (consisting only of upper and lowercase letters, spaces, and numbers) they want to input. These strings need to be stored in an array. Then I created a boolean method to be able to tell if those strings are palindromic (ignoring spaces and cases). If it is palindromic then I add to the result list to print later on. I am confused on how to ask the user to input that exact amount of strings and how to check each individual string. I must use StringBuilder. This is what I have so far (it's kind of a mess, sorry). I feel like I'm using the StringBuilder/array wrong, how can I fix this?
public class Palindromes {
public static void main(String[] args) {
int numOfStrings;
Scanner scan = new Scanner(System.in); // Creating Scanner object
System.out.print("Enter the number of strings: ");
numOfStrings = scan.nextInt();
System.out.print("Enter the strings: ");
StringBuilder paliString = new StringBuilder(numOfStrings);
for(int n=0; n < paliString; n++){
paliString[n] = scan.nextLine();
scan.nextLine();
String[] stringPali = new String[numOfStrings];
StringBuilder str = paliString;
if(isPali(userString)){
paliString = append.userString;
}
System.out.println("The palindromes are: " + userString ";");
}
static boolean isPali(String userString) {
int l = 0;
int h = userString.length() - 1;
// Lowercase string
userString = userString.toLowerCase();
// Compares character until they are equal
while (l <= h) {
char getAtl = userString.charAt(l);
char getAth = userString.charAt(h);
// If there is another symbol in left
// of sentence
if (!(getAtl >= 'a' && getAtl <= 'z'))
l++;
// If there is another symbol in right
// of sentence
else if (!(getAth >= 'a' && getAth <= 'z'))
h--;
// If characters are equal
else if (getAtl == getAth) {
l++;
h--;
}
// If characters are not equal then
// sentence is not palindrome
else
return false;
}
// Returns true if sentence is palindrome
return true;
}
}
SAMPLE RESULT:
Enter the number of strings: 8
Enter the strings:
Race Car
Mountain Dew
BATMAN
Taco Cat
Stressed Desserts
Is Mayonnaise an instrument
swap paws
A Toyotas a Toyota
The palindromes are: Race Car; Taco Cat; Stressed Desserts; swap paws; A Toyotas a Toyota
As I think the best way to answer this is to help you learn in small steps, I tried to stick with your initial idea on how to solve this and edited your main method with minimal changes.
This one does the trick.
public static void main(String[] args) {
int numOfStrings;
Scanner scan = new Scanner(System.in); // Creating Scanner object
System.out.print("Enter the number of strings: ");
numOfStrings = scan.nextInt();
scan.nextLine(); // you need this to catch the enter after the integer you entered
System.out.print("Enter the strings: ");
StringBuilder paliString = new StringBuilder();
for (int n = 0; n < numOfStrings; n++) {
String userString = scan.nextLine();
if (isPali(userString)) {
if (paliString.length() > 0) {
paliString.append("; ");
}
paliString.append(userString);
}
}
System.out.println("The palindromes are: " + paliString);
}
Key changes:
I added scan.nextLine(); right after reading the number of strings. This handles the newline you get when the user hits enter.
You don't need to initialize the StringBuilder with numOfStrings. This just preallocates the size of the StringBuilder in characters. Not the number of strings. Either way, it's not necessary. StringBuilder grows as needed.
I suggest you inspect what I did inside the for-loop. This was the biggest mess and changed significantly.
Last but not least: Writing the result needs to be outside of the for-loop, after all palindromes have been added to the StringBuilder.
Edit
Based on your comment, in this next iteration, I changed the usage of StringBuilder to the usage of an ArrayList. (Which is something completely different)
I am using it here because Lists in Java grow on demand. And since the number of palindromes is probably not equal to the number of input strings, this is the way to go. To really assign it to an array, one could always call String[] paliStringsArray = paliStrings.toArray(new String[]{}); but as ArrayLists already use an underlying array and are not necessary to to generate the output you want, I didn't put it into the new version.
Please compare the differences of this step to the previous version. I also added this String.join("; ", paliStrings) part, which creates the output you want.
public static void main(String[] args) {
int numOfStrings;
Scanner scan = new Scanner(System.in); // Creating Scanner object
System.out.print("Enter the number of strings: ");
numOfStrings = scan.nextInt();
scan.nextLine(); // you need this to catch the enter after the integer you entered
System.out.print("Enter the strings: ");
List<String> paliStrings = new ArrayList<>();
for (int n = 0; n < numOfStrings; n++) {
String userString = scan.nextLine();
if (isPali(userString)) {
paliStrings.add(userString);
}
}
System.out.println("The palindromes are: " + String.join("; ", paliStrings));
}
And now to the last step. Arvind Kumar Avinash actually solved a part that I also missed in the initial question. (I'll read more carefully in the future). He was validating the user input. So for the last iteration, I added his validation code in a modified way. I put it into a method as I think that makes things clearer and gets rid of the necessity of a the boolean valid variable.
public static void main(String[] args) {
int numOfStrings;
Scanner scan = new Scanner(System.in); // Creating Scanner object
System.out.print("Enter the number of strings: ");
numOfStrings = scan.nextInt();
scan.nextLine(); // you need this to catch the enter after the integer you entered
System.out.print("Enter the strings: ");
List<String> paliStrings = new ArrayList<>();
for (int n = 0; n < numOfStrings; n++) {
String userString = readNextLine(scan);
if (isPali(userString)) {
paliStrings.add(userString);
}
}
System.out.println("The palindromes are: " + String.join("; ", paliStrings));
}
static String readNextLine(Scanner scanner) {
while (true) {
String userString = scanner.nextLine();
if (userString.matches("[A-Za-z0-9 ]+")) {
return userString;
} else {
System.out.println("Error: invalid input.");
}
}
}
I need to ask the user the number of strings (consisting only of upper
and lowercase letters, spaces, and numbers) they want to input. These
strings need to be stored in an array.
I have done the above part of your question. I hope, this will give you direction to move forward.
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
boolean valid = true;
int numOfStrings = 0;
do {
valid = true;
System.out.print("Enter the number of strings: ");
try {
numOfStrings = Integer.parseInt(scan.nextLine());
} catch (NumberFormatException e) {
System.out.println("Error: invalid input.");
valid = false;
}
} while (!valid);
String[] stringPali = new String[numOfStrings];
String input;
for (int i = 0; i < numOfStrings; i++) {
do {
valid = true;
System.out.print("Enter a string consisting of only letters and digits: ");
input = scan.nextLine();
if (!input.matches("[A-Za-z0-9 ]+")) {
System.out.println("Error: invalid input.");
valid = false;
}
} while (!valid);
stringPali[i] = input;
}
}
}
A sample run:
Enter the number of strings: a
Error: invalid input.
Enter the number of strings: 3
Enter a string consisting of only letters and digits: Arvind
Enter a string consisting of only letters and digits: Kumar Avinash
Enter a string consisting of only letters and digits: !#£$%^&*()_+
Error: invalid input.
Enter a string consisting of only letters and digits: Hello #
Error: invalid input.
Enter a string consisting of only letters and digits: Hello 123
Feel free to comment in case of any doubt/issue.
Wish you all the best!
[Update]
Based on your request, I have posted the following update which asks for the strings only once and then allows the user to enter all the strings one-by-one:
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
boolean valid = true;
int numOfStrings = 0;
do {
valid = true;
System.out.print("Enter the number of strings: ");
try {
numOfStrings = Integer.parseInt(scan.nextLine());
} catch (NumberFormatException e) {
System.out.println("Error: invalid input.");
valid = false;
}
} while (!valid);
String[] stringPali = new String[numOfStrings];
String input;
System.out.println("Enter " + numOfStrings + " strings consisting of only letters and digits: ");
for (int i = 0; i < numOfStrings; i++) {
do {
valid = true;
input = scan.nextLine();
if (!input.matches("[A-Za-z0-9 ]+")) {
System.out.println("Error: invalid input.");
valid = false;
}
} while (!valid);
stringPali[i] = input;
}
}
}
A sample run:
Enter the number of strings: 3
Enter 3 strings consisting of only letters and digits:
Arvind
Kumar
He$ll0
Error: invalid input.
Avinash
Feel free to comment in case of any doubt.
This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed 6 years ago.
First of all, apologies for the title gore.
The specific thing I am trying to understand here in the following piece of code is why the getNumber function, when called the second time, continues to return the same initial user input and doesn't ask for a new user input.
/*Write an application that inputs one number consisting
of five digits from the user, separates the number into its individual digits and prints the digits
separated from one another by three spaces each.
*/
public class SeparatingDigitsOfInt {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
boolean check =false;
String s=null;
while (check==false)
{
s= Integer.toString(getNumber()); //since user input was a string, getNumber returns 0 and we enter the while loop below
while (s.equals("0"))// here i am trying to get another input from user because first input was invalid
{
System.out.println("Try that again!");
s= Integer.toString(getNumber()); // why getNumber continues to return xyz here and doesn't ask for new user input
check =false;
}
check =true;
}
System.out.println(s);
while(s.length()!= 5){
System.out.println("Input number is not of 5 digits!");
System.out.println("Please enter a 5 digit number");
s = input.next();
}
String result = "";
for (int i = 0; i < s.length(); i++) {
result= result + s.charAt(i) + " ";
}
System.out.println("Result is :" + result);
}
public static int getNumber(){
try {
System.out.println("Enter a 5 digit number");
return input.nextInt(); // user inputs string xyz
}
catch (InputMismatchException e) {
System.out.println("Please enter only numbers");
return 0;// since user inputs xyz, so 0 is returned by getNumber
}
}
}
In documentation stated :
If the translation is successful, the scanner advances past the input
that matched
So that means if it translation was not successful, it won't advance
Tells the user if the number entered is even or even. I need help with the input validation. The validation i need do is that the user cannot entered anything but a number. Trying to do the validation without the try and catch method.
import java.util.Scanner;
public class oddoreven {
public static void main (String [] args) {
Scanner input = new Scanner (System.in);
//declaractions
int num;
//while loop
do{
System.out.println("PLease enter a number to see whether it is even or odd. To end tyype in -99.");
num = input.nextInt();
// input valid
}while(num != -99); // loop ends
// begins the method
public static void is_odd_or_even_number(int number){
int rem = number%2;
\
You can call Scanner.hasNextInt() to determine if the next input is an int (and consume anything else). Also, you might make an infinite loop and break when the input is -99 (or 99, your code tests for 99 but your prompt says -99). Finally, you should call your method. Something like,
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num;
do {
System.out.println("Please enter a number to see whether it is "
+ "even or odd. To end type in -99.");
if (input.hasNextInt()) {
num = input.nextInt();
if (num != -99) { // <-- directions say -99.
is_odd_or_even_number(num);
} else {
break;
}
} else {
System.out.printf("%s is not a valid int.%n", input.nextLine());
}
} while (true);
}
You can use Scanner.nextLine() to get a string input. Then loop through the characters to make sure they are all digits. (assuming non-negative integers only)
string rawInput = input.nextLine();
boolean validInput = true;
for (char c : rawInput) {
if (!Character.isDigit(c)) {
validInput = false;
break;
}
}
if (validInput) {
int num == Integer.parseInt(rawInput);
// proceed as normal
}
else {
// invalid input, print out error message
}
You can use regex to check whether all the characters of string entered by user are digits or not,
num.matches("[0-9]+") // return true if all characters are digits
or
num.matches("^[0-9]*$") // return true if all characters are digits
but before that change your num = input.nextint() to num = nextLine() and make num as String. if you dont do this there is no need of validating user input as you are requiring.
Scenario One: User is asked for 5 digit Input Number and 3 digit Code and then those are replaced in file name and inside the file.
Scenario Two: User is asked for 5 digit Input Number AND then ASKED if they want to input/change the 3 digit code. If yes then they can input a 3 digit code.
Current Code:
package blah blah
import all stuffs...
public class NumbChanger{
public static void main(String[] args) {
try {
Scanner user = new Scanner(System.in);
String inputCode= "";
System.out.print("Enter a xml file directory: "); // Enter xml file directory.
String directory = user.nextLine();
System.out.print("Enter the 5 digit starting Number: ");
int inputNumber = user.nextInt();
System.out.print("Do you want to change the code?");
boolean yesChange = user.hasNext();
if (!yesChange){
} else {
System.out.print("Enter the 3 character Code: ");
inputCode = user.next();
}
user.close();
Path folder = Paths.get(directory);
FilenameFilter xmlFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
String lowercaseName = name.toLowerCase();
if (lowercaseName.endsWith(".xml")) {
return true;
} else {
return false;
}
}
};
//this is the list of files
File[] allFiles = folder.toFile().listFiles(xmlFilter);
if (allFiles == null) {
throw new IOException("No files found");
}
String fileName;
for(File aFile : allFiles) {
if (aFile.isFile()) {
fileName = aFile.getName();
String oldNumber = fileName.substring(
((fileName.lastIndexOf(".")) - 12), (fileName.lastIndexOf(".")) - 4);
String oldCode = fileName.substring(
((fileName.lastIndexOf(".")) - 3), (fileName.lastIndexOf(".")));
if (!yesChange){
} else {
inputCode = fileName.substring(
((fileName.lastIndexOf(".")) - 3), (fileName.lastIndexOf(".")));
}
String newNumber = String.valueOf(inputNumber++);
String newFileName = fileName.replaceAll(
oldNumber, newNumber);
if (!yesChange){
} else {
newFileName = newFileName.replaceAll(oldCode, inputCode);
}
//renaming the file
Path newFilePath = Files.move(aFile.toPath(),
aFile.toPath().resolveSibling(newFileName));
//replacing the entry # within the XML
String content = new String(Files.readAllBytes(newFilePath),
StandardCharsets.UTF_8);
content = content.replaceAll(oldNumber, newNumber);
content = content.replaceAll(oldCode, inputCode);
Files.write(newFilePath, content.getBytes(StandardCharsets.UTF_8));
}
}
System.out.print(allFiles.length + " xml files were changed.");
} catch (Exception ex) {
ex.printStackTrace();
} finally {
System.out.println(" Good Job!");
System.exit(0);
}
}
}
Reflection on above code.
Currently I make it work if they enter values for both. Where am I going wrong?
Further enhancements:
Check the length of code.
I understand I can do a simple
if (inputCode.length == 3){
}
else {
System.out.print ln ("Error")
}
But Im not to privy with booleans and while loops and if the user enters a different value I want them to prompt again versus having to run the program again.
thanks in advance! :)
Im not sure I understand your question, but wouldn't
System.out.print("Enter the 5 digit starting Number: ");
int inputNumber = user.nextInt();
while(String.valueOf(inputNumber).length() != 5) {
System.out.println("Please enter a 5 digit number.");
inputNumber = user.nextInt();
}
do the job?
If the number is not 5 digits long the user is asked to enter a new one.
You cant use .length() on an Integer, so you will have to convert it to a String first. Hence the line
String.valueOf(inputNumber).length()
I am trying to make a simple game of hangman in Java. I do have a text file named dictionary.txt containing 120K words from the English dictionary. The problem arises when I am going to prompt the user for a word length and displaying number of words with that particular length.
After spending a fair amount of time here and googling I have gotten this far but now I am stuck:
import java.util.Scanner;
import java.io.*;
import java.io.IOException;
public class Hangman
{
public static void main(String[] args) throws IOException
{
// declaring variables
int wordLength;
int guessNumber;
// initiate the scanner
Scanner keyboard = new Scanner( System.in );
// read the dictionary file
File file = new File("dictionary.txt");
StringBuilder contents = new StringBuilder();
BufferedReader reader = null;
// prompt the user for word length
System.out.println("Welcome to Hangman. Let's play! ");
System.out.println("Please enter the desired word length: ");
wordLength = keyboard.nextInt();
while(wordLength < 0 || wordLength > 26)
{
System.out.println("This is not a valid word length. ");
System.out.println("Please enter the desired word length: ");
wordLength = keyboard.nextInt();
}
// prompt the user for number of guesses
System.out.println("How many guesses do you want to have? ");
guessNumber = keyboard.nextInt();
while(guessNumber < 0)
{
System.out.println("Number of guesses has to be a postive integer. ");
System.out.println("Please enter the desired number of guesses: ");
guessNumber = keyboard.nextInt();
}
}
}
My goal is to prompt the user for a word length and if the desired word length does not exist in the dictionary.txt file then it keeps asking until a valid response is given.
I would also like to be able to prints how many words have a given word length (e.g if user types in "10", then it displays how many words in dictionary.txt have the length of 10 letters.
The following part of the code is the one I hope to replace with code that reads the txt file and acts thereafter:
while(wordLength < 0 || wordLength > 26)
{
System.out.println("This is not a valid word length. ");
System.out.println("Please enter the desired word length: ");
wordLength = keyboard.nextInt();
}
It is possible that I have taken the wrong approach, so all feedback is very welcome!
This code can be used to establish a count of words of each word length.
// map where the key is the length of a word and
// the value is the number of words of that length
Map<Integer, Integer> numberOfWordsOfLength = new HashMap<>();
Scanner dictionaryScanner = new Scanner(file);
while (dictionaryScanner.hasNext())
{
String word = dictionaryScanner.next();
int wordLength = word.length();
numberOfWordsOfLength.put(wordLength, 1 +
numberOfWordsOfLength.containsKey(wordLength) ?
numberOfWordsOfLength.get(wordLength) :
0);
}
Then, when you want to know if there are any words of a given length, you can use this.
numberOfWordsOfLength.containsKey(length)
When you want to get the number of words in the dictionay that have a given length, you can use this.
numberOfWordsOfLength.get(length)
Later, when you want to select a random word of a given length, you can do something like this.
int wordIndex = new Random().nextInt(numberOfWordsOfLength.get(length));
Scanner dictionaryScanner = new Scanner(file);
String word;
while (dictionaryScanner.hasNext())
{
String candidateWord = dictionaryScanner.next();
if (candidateWord.length() != length) continue;
if (wordIndex == 0)
{
word = candidateWord;
break;
}
--wordIndex;
}
Try this:
try
{
Scanner input = new Scanner(file);
boolean flag = true;
while(flag)
{
ArrayList<String> words = new ArrayList<String>(120000);
while(input.hasNextLine())
{
String s = in.nextLine();
if(s.length() == wordLength)
{
words.add(s);
}
}
if(words.isEmpty())
{
System.err.print("Invalid word length, please try again\n>");
wordLength = keyboard.nextInt();
}
else
{
flag = false;
System.out.println("There were " + words.size() + " such words");
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
Does it work?