Limiting the length of an input to x amount of digits - java

I'm running a java program I created that stores data inputted by user. Specifically 4 array lists which are songName, songArtist, songYear & songAlbum.
I have a user input for "songYear" and I only want the program to accept a maximum of 4 digits in length and give an error otherwise, how can this be achieved?
here's the code I have for my add entry method:
public void addEntry(){
String newName = ui.getString("Enter the name of the track");
songName.add(newName);
String newArtist = ui.getString("Who performs this track");
songArtist.add(newArtist);
String newAlbum = ui.getString("What album is this track from");
songAlbum.add(newAlbum);
System.out.print("What year was the track released? ");
int newYear=input.nextInt(4);
songYear.add(newYear);
System.out.println("\n" + "Thank you, " +songName.get(songName.size()-1) + " has been added to the library.");
System.out.println("\n" + "Press 2 to view your library." + "\n");
}

You can use regex like: ^.{4}$
Means only if user typed 4 digits - return true, otherwise return false
To be sure that user used 4 numbers YYYY use something like:
^(?=[1-9]+)\d{4}$
Makes sure the year is 1 or 2 followed by three numbers; valid ranges in this case would be 1000-2999
^(?=[1-2][0-9]+)\d{4}$
Finally your code should be like:
if(inputUserStr.matches("^(?=[1-2][0-9]+)\d{4}$")){
// do some stuff
}
else{
// print error about valid input form [YYYY]
}

Depends entirely on the language but some approaches are:
check the string input using a len function; or
convert it to an integer and ensure it's less than 10,000; or
a regular expression like ^\d{1,4}.
No doubt there'll be other validation checks such as ensuring string input is all-numeric, and you're not trying to input a song that was written twenty years in the future, but they're added checks you should consider.

1) Accept the user's input and using the substring method, save only the first four characters (Specify to user that first 4 characters are considered).
2) You can ask the user to reenter the value if it is not 4 characters:
Scanner sc = new Scanner(System.in);
String a = sc.next();
if (a.matches("...."))
{
System.out.print(a);
}
else
{
System.out.print("Input again:" );
a = sc.next();
}
I've written a sample regex for 4 characters. But you can always change it.

Related

How can I obtain the first character of a string that is given by a user input in java

I want the user to input a String, lets say his or her name. The name can be Jessica or Steve. I want the program to recognize the string but only output the first three letters. It can really be any number of letters I decide I want to output (in this case 3), and yes, I have tried
charAt();
However, I do not want to hard code a string in the program, I want a user input. So it throws me an error. The code below is what I have.
public static void main(String args[]){
Scanner Name = new Scanner(System.in);
System.out.print("Insert Name here ");
System.out.print(Name.nextLine());
System.out.println();
for(int i=0; i<=2; i++){
System.out.println(Name.next(i));
}
}
the error occurs at
System.out.println(Name.next(i)); it underlines the .next area and it gives me an error that states,
"The Method next(String) in the type Scanner is not applicable for arguments (int)"
Now I know my output is supposed to be a of a string type for every iteration it should be a int, such that 0 is the first index of the string 1 should be the second and 2 should be the third index, but its a char creating a string and I get confused.
System.out.println("Enter string");
Scanner name = new Scanner(System.in);
String str= name.next();
System.out.println("Enter number of chars to be displayed");
Scanner chars = new Scanner(System.in);
int a = chars.nextInt();
System.out.println(str.substring(0, Math.min(str.length(), a)));
The char type has been essentially broken since Java 2, and legacy since Java 5. As a 16-bit value, char is physically incapable of representing most characters.
Instead, use code point integer numbers to work with individual characters.
Call String#codePoints to get an IntStream of the code point for each character.
Truncate the stream by calling limit while passing the number of characters you want.
Build a new String with resulting text by passing references to methods found on the StringBuilder class.
int limit = 3 ; // How many characters to pull from each name.
String output =
"Jessica"
.codePoints()
.limit( limit )
.collect(
StringBuilder::new,
StringBuilder::appendCodePoint,
StringBuilder::append
)
.toString()
;
Jes
When you take entry from a User it's always a good idea to validate the input to ensure it will meet the rules of your code so as not to initiate Exceptions (errors). If the entry by the User is found to be invalid then provide the opportunity for the User to enter a correct response, for example:
Scanner userInput = new Scanner(System.in);
String name = "";
// Prompt loop....
while (name.isEmpty()) {
System.out.print("Please enter Name here: --> ");
/* Get the name entry from User and trim the entry
of any possible leading or triling whitespaces. */
name = userInput.nextLine().trim();
/* Validate Entry...
If the entry is blank, just one or more whitespaces,
or is less than 3 characters in length then inform
the User of an invalid entry an to try again. */
if (name.isEmpty() || name.length() < 3) {
System.out.println("Invalid Entry (" + name + ")!\n"
+ "Name must be at least 3 characters in length!\n"
+ "Try Again...\n");
name = "";
}
}
/* If we get to this point then the entry meets our
validation rules. Now we get the first three
characters from the input name and display it. */
String shortName = name.substring(0, 3);
System.out.println();
System.out.println("Name supplied: --> " + name);
System.out.println("Short Name: --> " + shortName);
As you can see in the code above the String#substring() method is used to get the first three characters of the string (name) entered by the User.

When calling own method, Old String values are left over

When I get the unwanted input I called the method again, but then on the second iteration there is still a char left on the String. Why doesn't it make a brand new string and replace the older value?
SO first i type in "mmmm" into the scanner, which sets off the condition in the if statement and calls createSocial(), which then reruns the loop, and I type in a new input of 5555. Now this is what I don't get: when I print out the new Strings they show up as 5555, but then printing them in the loop has the left over "m", why?
public class test {
public static String createSocial() {
Scanner sc = new Scanner(System.in);
String social = sc.nextLine();
String digit = social;
System.out.println(social + " SOCIAL");
System.out.println(digit + " DIGIT");
if (social.length() != 4) {
System.out.println("You did not type 4 digits, try again");
createSocial();
}
//check non-integers
while(digit.length() > 0) {
System.out.println( digit.charAt(0) + "<---");
if(Character.isDigit( digit.charAt(0) ) == false) {
System.out.println("You did not type your last 4 digits correctly, try again");
createSocial();
}
digit = digit.substring(1);
}
return social;
}
}
This is my output :
enter the last 4 digits of your Social Security number
mmmm //(This is my first input for the scanner)
mmmm SOCIAL
mmmm DIGIT
m<---
You did not type your last 4 digits correctly, try again
5555 //(this is my input for the scanner the second time around)
5555 SOCIAL
5555 DIGIT
5<---
5<---
5<---
5<---
m<---
You did not type your last 4 digits correctly, try again
The reason you see the m as in:
5<---
5<---
5<---
5<---
m<---
is simply because you don't clear the social string variable before you embark on your recursion call. In reality when making this recursion call you should be doing it this way:
social = createSocial();
This way you are guaranteed social will always hold the true value from that recursion call and not a value from a previous recursion call. If you don't take the return value from the createSocial() method you will never get the new result because the scope of the social variable is local to the method itself. You need to accept the return value just as you do on your very first initial call to the createSocial() method.
But that's not all, you also need to update the digit variable content after every recursive call (digit = social;). In my opinion this is more complicated than necessary. I understand why you've added the digit variable but if you take a close look at the code you could have accomplished the same thing by just continuing to utilize the social variable to carry out the numerical breakdown. You just need to hold the original value within social before the numerical breakdown is carried out within a variable that can be returned by the method, for example:
private static int methodCalls = 0; // Class Global Member Variable
public static String createSocial() {
methodCalls++;
Scanner sc = new Scanner(System.in);
String social = sc.nextLine();
System.out.println(social + " SOCIAL");
if (social.length() != 4) {
System.out.println("You did not type 4 digits, try again");
social = createSocial();
}
// returnResult will eventually will hold the
// valid result to return.
String returnResult = social;
//check non-integers
while (social.length() > 0) {
System.out.println(social.charAt(0) + " <--- Method call: " + methodCalls);
if (Character.isDigit(social.charAt(0)) == false) {
System.out.println("You did not type your last 4 digits correctly, try again");
social = createSocial();
}
social = social.substring(1);
}
methodCalls--;
return returnResult;
}
Using your posted example parameters (mmmmm and 5555) you might use the above code like this:
System.out.println(createSocial());
and after entering mmmmm and 5555 the output result to console would look like this:
mmmmm
mmmmm SOCIAL
You did not type 4 digits, try again
5555
5555 SOCIAL
5 <--- Method call: 2
5 <--- Method call: 2
5 <--- Method call: 2
5 <--- Method call: 2
5 <--- Method call: 1
5 <--- Method call: 1
5 <--- Method call: 1
5 <--- Method call: 1
5555
Why all the 5 <---? Because of the single recursive call. The 5's that are labeled Method call: 1 is the initial call to the createSocial() method. Any method call over 1 is a recursive call. Upon each call four 5 <---'s are listed.
This can all be done in a much easier fashion and recursion is not required to carry out this task, a loop can be used instead, for example:
public static String createSocial() {
String ls = System.lineSeparator();
Scanner sc = new Scanner(System.in);
String social = "";
while (social.equals("")) {
System.out.print("Please enter the last four digits of " + ls
+ "your Social Security Number: --> ");
social = sc.nextLine();
if (!social.matches("\\d{4}")) {
System.err.println("Invalid Entry! Please Try Again..." + ls);
social = "";
}
}
return social;
}
But if recursion is a requirement then you can do it this way:
public static String createSocial() {
String ls = System.lineSeparator();
Scanner sc = new Scanner(System.in);
String social = "";
System.out.print("Please enter the last four digits of " + ls
+ "your Social Security Number: --> ");
social = sc.nextLine();
if (!social.matches("\\d{4}")) {
System.err.println("Invalid Entry! Please Try Again..." + ls);
social = createSocial();
}
return social;
}
Using Java's String#matches() method along with a small Regular Expression to check for data entry validity removes the need for a lot of code and makes things much easier to read. The Regular Expression (RegEx) used within the matches() method of the IF statement condition in the two above code examples
if (!social.matches("\\d{4}")) {
basically means this: If the User entry string is not a four digit integer value then display an "Invalid Entry!" message.

How to repeatedly enter a string until user enters keyword to stop loop in java

I am stuck in this program that is string method, my issue is that I cannot get the loop to stop and the program to print the output that is currently stored after the keyword has been entered. I am not trying to compare strings, I am trying to input multiple strings and add a word, in this case, "not" to the strings until the word "stop" is entered. Once "stop" has been entered. the system will output the entire string stored.
Here is the question for the program:
(StringConcat.java) This program asks the user to repeatedly enter a String. It ,should concatenate those Strings together, but insert spaces and the word “not” between every pair of words the user enters. Stop when the user enters the String “stop”. Display the final String. For instance, the program output might look like:
Please enter some Strings:
"Such"
"eyes"
"you"
"have"
"stop"
"Such not eyes not you not have"
Here is my code so far:
import java.util.*;
public class StringConcat{
public static void main(String [] args){
Scanner sc = new Scanner(System.in);
String s = new String();
System.out.print("Please enter some Strings: ");
for(int x=0; x<s.length(); x++){
s = sc.nextLine();
s = s + "not ";
if(s == "stop"){
System.out.println(s);
break;
}
else{
continue;
}
}
}
}
Several issues with your code:
(1) Why do you use a for loop and iterate up to s.length() when the length of s (which is 0 at that point) has nothing to do with your problem?
You need a loop which has not predefined number of iterations like a while (true) from which you will exit with a break.
(2) In each iteration you get the user's input and store it in s, so you lose all previous values.
You need a separate variable to store the user's input.
(3) The continue statement is not needed as the last statement in a loop.
(4) Because at each iteration you append " not " at the end, after the loop has finished you must delete that last " not " from s
(5) Don't use == when you compare strings. There is the method equals() for this.
This is my solution:
Scanner sc = new Scanner(System.in);
String s = "";
System.out.print("Please enter some Strings: ");
while (true){
String input = sc.nextLine();
if(input.equalsIgnoreCase("stop"))
break;
s += input + " not ";
}
if (s.length() >= 5)
s = s.substring(0, s.length() - 5);
System.out.println(s);
Use while loop.
Why while loop?
Usually we have to use while loops always when we don't know the number of loops we will do. In this case only when the user inputs "stop".
So you need a String field to hold the user words. Also we can use a number field to track if is the first or the second word, thinkg in append the "not" word.
Then, take a look in this example:
Scanner s = new Scanner(System.in);
String currentAnswer = "";
String userWords = "";
int tracker = 0;
while (!currentAnswer.equals("stop")){
currentAnswer = s.nextLine();
userWords += currentAnswer + " ";
if (tracker % 2 != 0) {
userWords += "not ";
}
tracker++;
}
System.put.println(userWords);
This can be done using for loop too but I really recommend the while loop to this case.
EDIT:
As you saw, I used equals() instead == to compare two Strings because we are wiling to check for its value, not for its object equality.
When we use == operator we are trying to check if two objects target to the same memory adress, but we only want to know if two Strings have the same value.
For this case is valid to know that we can compare it using other ways, such as Objects.equals() or even contentEquals().
Check this discussion to learn more about comparing strings.

Check String is in a range of numbers Java

Trying to design a simple lottery program. Everything works except checking if the numbers entered are between 1 to 59.
Exercise says the numbers must be stored in a String variable.
so
if(num<0 || num>59) //wont work for me
Tried making another variable
int numConverted = Integer.parseInt(num)
We haven't covered converting String to int in class though so I don't think this is what expected. Got confused trying that way anyway so probably this is wrong.
Here is the code I have currently.
{
Scanner scan = new Scanner(System.in);
String num=""; //num variable is empty untill user inputs numbers
for(int i =0; i<6; i++)
{
System.out.println("Enter your number between 1-59");
num = num +" "+ scan.nextLine();
}
System.out.println("Ticket printed £2. Your numbers are " + num);
}
In your posted code it's obvious that you want the User to supply 6 specific numerical values. These values are appended to the String variable named num (space delimited). You need to obviously do a few things here:
1) Make sure the value supplied by the user is indeed a numerical value;
2) Make sure the numerical values supplied fall within the minimum and maximum scope of the lottery itself (which you have stated is: 1 to 59);
3) Make sure the number entered by the User hasn't been supplied already.
You've been tasked to store the entered values into a String data type variable and that is all fine but at some point you want to carry out value comparisons to make sure that all the entered values actually play within the limits of the lottery.
When the User completes his/her entries, you end up with a space delimited string held in the num string variable. You now need to make sure that these values entered are indeed....numbers from 1 to 59 and none contain alpha characters.
In my opinion (and this is only because you need to store entered values into a String variable), it's best to use your String variable to gather User input, then test the input to make sure it is indeed a string representation of an actual integer number. Once this is established then we test to make sure if falls within the value min/max limits (1-59). Now we need to test to make sure the number entered hasn't already been entered before for this ticket.
Of course with each test described above, if one fails then the User should be prompted to re-enter a proper value. You can do this by utilizing a while loop. Plenty examples of this in StackOverflow but here's a quick example:
Scanner scan = new Scanner(System.in);
String ticketNumbers = "";
for(int i = 0; i < 6; i++) {
Boolean isOK = false;
while (!isOK) {
System.out.println("\nPlease enter your desired 6 ticket numbers:\n"
+ "(from 1 to 59 only)");
String num = scan.nextLine();
//Is the string entered an actual integer number?
//We use the String.matches() method for this with
//a regular expression.
if(!num.matches("\\d+")) {
System.out.println("You must supply a numerical value! "
+ "Try Again...");
continue;
}
if (ticketNumbers.contains(num + " ")) {
System.out.println("The number you supplied has already been chosen!"
+ " Try Again...");
continue;
}
if (Integer.parseInt(num) >= 1 && Integer.parseInt(num) <= 59) {
ticketNumbers+= num + " ";
isOK = true;
}
else {
System.out.println("The number you supply must be from "
+ "1 to 59! Try Again...");
}
}
}
System.out.println("Ticket printed £2. Your numbers are " + ticketNumbers);
How about -
if(Integer.parseInt(num) < 0 || Integer.parseInt(num) > 59)
This should work, place it after the input.
If it works, please mark this as correct, I need the rep!!!
Easy way would be add available numbers (suppose it wont grow more than 60. You can use a loop to add to this as well)
String numbers[] = {"1","2","3", "..."};
Then inside the loop
Arrays.asList(numbers).contains(num);
You can remove prefixing zero in order avoid conflicts with values like '02'
Here everything is String related.
If you don't want to explicitly convert to int, you could use a regular expression.
if (num.matches("[1-5]?[0-9]")) {
...
This checks whether the String consists of (1) maybe a digit from 1 to 5, followed by (2) definitely a digit from 0 to 9. That'll match any number in the range 0-59.
If you've got a whole series of numbers separated by spaces, you could expand this to cover a whole series like this.
if (num.matches("([1-5]?[0-9]\\s+)*[1-5]?[0-9]")) {
This matches any number of repetitions (including zero) of "a number followed by spaces", followed by a single repetition without a space. The "\\s" means "any whitespace character", the "+" after it means "one or more of what precedes", and the "*" means "zero more of what precedes" - which in this case is the term in parentheses.
Oh I see what you are trying to do
This is what you want
Scanner scan = new Scanner(System.in);
String allNums = "";
for(int i =0; i<6; i++)
{
System.out.println("Enter your number between 1-59");
int num = scan.nextInt();//Take the number in as an int
if(num >0 && num < 59)//Check if it is in range
{
allNums += num + " ";//if it is add it to a string
}
else
{
System.out.println("Number not in range");
i--;//go back one iteration if its not in range
}
}
System.out.println("Ticket printed £2. Your numbers are " + allNums);

Breaking up a single user input and storing it in two different variables. (Java)

I'm very new to programming, especially Java. I need to create a program that counts how many orders each entry at a restaurant gets ordered. The restaurant carries 3 entries, hamburgers, salad, and special.
I need to set up my program so that the user inputs, say, "hamburger 3", it would keep track of the number and add it up at the end. If the user inputs "quit", the program would quit.
System.out.println("Enter the type (special, salad, or hamburger) of entrée followed by the number, or quit to exit the program.");
I'm thinking about using a while loop, setting it so if the user input != to "quit", then it would run.
What's difficult for me is I don't know how to make my program take into account the two different parts of the user input, "hamburger 3" and sum up the number part at the end.
At the end, I want it to say something like "You sold X hamburgers, Y salads, and Z specials today."
Help would be appreciated.
You'll probably want three int variables to use as a running tally of the number of orders been made:
public class Restaurant {
private int specials = 0;
private int salads = 0;
private int hamburger = 0;
You could then use a do-while loop to request information from the user...
String input = null;
do {
//...
} while ("quite".equalsIgnoreCase(input));
Now, you need some way to ask the user for input. You can use a java.util.Scanner easily enough for this. See the Scanning tutorial
Scanner scanner = new Scanner(System.in);
//...
do {
System.out.println("Enter the type (special, salad, or hamburger) of entrée followed by the number, or quit to exit the program.");
input = scanner.nextLine();
Now you have the input from the user, you need to make some decisions. You need to know if they entered valid input (an entree and an amount) as well as if they entered an available option...
// Break the input apart at the spaces...
String[] parts = input.split(" ");
// We only care if there are two parts...
if (parts.length == 2) {
// Process the parts...
} else if (parts.length == 0 || !"quite".equalsIgnoreCase(parts[0])) {
System.out.println("Your selection is invalid");
}
Okay, so we can now determine if the user input meets or first requirement or not ([text][space][text]), now we need to determine if the values are actually valid...
First, lets check the quantity...
if (parts.length == 2) {
// We user another Scanner, as this can determine if the String
// is an `int` value (or at least starts with one)
Scanner test = new Scanner(parts[1]);
if (test.hasInt()) {
int quantity = test.nextInt();
// continue processing...
} else {
System.out.println(parts[1] + " is not a valid quantity");
}
Now we want to check if the actually entered a valid entree...
if (test.hasInt()) {
int quantity = test.nextInt();
// We could use a case statement here, but for simplicity...
if ("special".equalsIgnoreCase(parts[0])) {
specials += quantity;
} else if ("salad".equalsIgnoreCase(parts[0])) {
salads += quantity;
} else if ("hamburger".equalsIgnoreCase(parts[0])) {
hamburger += quantity;
} else {
System.out.println(parts[0] + " is not a valid entree");
}
Take a look at The if-then and if-then-else Statements and The while and do-while Statements for more details.
You may also find Learning the Java Language of some help. Also, keep a copy of the JavaDocs at hand, it will make it eaiser to find references to the classes within the API
These two methods should be what you're looking for.
For splitting: String.split(String regex)
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)
For parsing String into an Interger: Integer.parseInt(String s)
http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#parseInt(java.lang.String)
You can split your strings using input.split(" "). This method gives you two strings - two parts of the main string. The character you splitted with (" ") won't be found in the string anymore.
To then get an integer out of your string, you can use the static method Integer.parseInt(inputPartWithCount).
I hope this helps!

Categories

Resources