Validate user input against ArrayList - java

I am having issues with the following part of my code.
when "nn" is entered i get invalid code.
when valid code is entered i get invalid code however this only happens once.
program doesn't seem to work as intended. Please assist.
System.out.println("ENTER CODE (nn to Stop) : ");
ArrayList<Product> list = new ArrayList<Product>();
.
.
.
.
ArrayList<Code> codeList = new ArrayList<Code>();
for (Product product : list) {
System.out.print("CODE : ");
String pcode = scan.next();
if (pcode.equalsIgnoreCase("nn")) {
break;
}
if (!(code.equalsIgnoreCase(product.getCode()))) {
System.out.println("Invalid code, please enter valid code.");
System.out.print("CODE : ");
pcode = scan.next();
}
System.out.print("QUANTITY : ");
int quan = scan.nextInt();
while (quan > 20) {
System.out.println("Purchase of more than 20 items are not allowed, please enter lower amount.");
System.out.print("QUANTITY : ");
quan = scan.nextInt();
}
codeList.add(new Code(pcode, quan));
}

You want continue instead of break.
Also, you should only call code = scan.next() once inside the loop; otherwise you'll skip over some items.
String code = scan.next();
boolean match = false;
for (Product product : list) {
if (code.equalsIgnoreCase(product.getCode())) {
match = true;
break;
}
}
// now only if match is false do you have an invalid product code.
Update:
I still can't get this to work. What I am trying to do is test user
input to make sure that product code exists, if not prompt that the
product code entered is invalid and asks for correct code. I also need
to have the condition to stop order when "nn" is entered. I have tried
while loops, do-while loops etc. i can't seem to get it right. Please
assist. My problem is with writing code for multiple conditions. When
one is working correctly the other isn't.
while (true) {
final String code = scan.next();
if (isExitCode(code)) {
break;
}
if (!isValidCode(code)) {
System.out.println("Invalid code, please enter valid code.");
continue;
}
int quantity = -1;
while (true) {
quantity = scan.nextInt();
if (!isValidQuantity(quantity)) {
System.out.println("bad quantity");
continue;
}
break;
}
// if you've got here, you have a valid code and a valid
// quantity; deal with it as you see fit.
}
Now you just need to write the methods isExitCode(), isValidCode(), and isValidQuantity().

Related

How can I get a multidimensional array to loop with string input?

Basically I'm making a program that reads from a multidimensional array to display it's corresponding information. What I want to do is make it so the while loop will continue to tell me I'm putting in the wrong class ID's until you put in a correct Class ID.
do
{
System.out.println("Please enter the name of your course to display it's information");
name = input.nextLine();
for(int x = 0; x <= classes.length; ++x)
{
if(name.equals(classes[x][0]))
{
i = true;
System.out.println("Course info: " + classes [x][0]);
System.out.println(classes[x][1]);
System.out.println(classes[x][2]);
x = classes.length;
}
else{
System.out.println("Wrong course id");
i = false;
input.next();
}
}
}
while (!(i));
System.out.println("This is the end of the program!");
System.exit(0);
First of all, try to keep good naming conventions. i is bad name for a flag variable. Name it boolean found or something. It will not only help other people read and understand your code, but it will help you in order find the logic you have to use as well.
Now, since you have input.next(); in else part, i guess you want to ask again for user input, until a something is found. So, a name = input.nextLine(); is required again in order to take new input. But in your case the else part can be removed completely and let the do-while do the work.
An example:
public class Classes {
private static final String[][] CLASSES = { { "Maths", "info" }, { "History", "info" }, { "Biology", "info" } };
public static void main(String[] args) {
boolean found = false;
String name;
Scanner input = new Scanner(System.in);
do {
System.out.println("Please enter the name of your course to display it's information");
name = input.nextLine();
for (int i = 0; i < CLASSES.length; i++) {
if (name.equals(CLASSES[i][0])) {
found = true;
System.out.println("Course info: " + CLASSES[i][0]);
System.out.println(CLASSES[i][1]);
// System.out.println(CLASSES[i][2]); //My CLASSES array, does not have 3 columns
break;// exit for loop
}
}
if (!found)
System.out.println("Wrong course id");
} while (!found);
input.close();
System.out.println("This is the end of the program!");
}
}

Comparing elements of ArrayList in loop gives unexpected result?

The following code checks only the first item in the ArrayList. When I type in an item that is in the ArrayList but not in the first position, I get my error message as "Please enter a valid name".
How can I fix this? Thank you!
Here is my code:
private ArrayList<Account> accounts = new ArrayList<>();
for(Account a : accounts)
{
while(true)
{
System.out.printf("Customer name: ");
String customerName = scanner.next();
if(customerName.equals(a.getName()))
{
System.out.println("You entered " + a.getName());
break;
}
else
{
System.out.println("Please enter a valid name");
}
}
}
You have to break from while. When you iterating on list you have to think about logic. Its can be like this code ;
ArrayList<Account> accounts = new ArrayList<>();
boolean isMatched = false;
while (true) {
for (Account account : accounts) {
System.out.printf("Customer name: ");
String customerName = scanner.next();
if (customerName.equals(account.getName())) {
isMatched = true;
break;
}
}
if (isMatched) {
System.out.println("You entered " + account.getName());
break;
}
System.out.println("Please enter a valid name");
}
PS: boolean value to when found the customer name for ending while loop.
The inner loop does do that:
while(true) {
has no purpose here. It simply keeps looping inside the outer loop, therefore always comparing against the same a account!
Basically you have to swap the two loops!
The problem is the infinite while loop.
while(true)
This loop breaks only when customerName == firstElement.Name, else it is an infinite loop. Instead I think what you want to try is moving the while loop outside the for loop. So the code will look something like this.
private ArrayList<Account> accounts = new ArrayList<>();
while(true)
{
System.out.printf("Customer name: ");
String customerName = scanner.next();
for(Account a : accounts){
if(customerName.equals(a.getName())){
System.out.println("You entered " + a.getName());
break;
}else{
System.out.println("Please enter a valid name");
}
}
}
The problem you have it's because you are only checking the first element all the time. Just after you entering your first element, (and breaking your loop while(1)) you will pass to the second one.
Imagine you have in your arrayList
"hello", "bye"
You'll be inside your loop until texting the first element ("hello").
Solution:
while(true)
{
System.out.printf("Customer name: ");
String customerName = scanner.next();
if (accounts.contains(customerName)){
System.out.println("You entered " + customerName);
break;
}
else{
System.out.println("Please enter a valid name");
}
}

for loop - looping more than its supposed to?

public static void choice( String arrayString[], double arrayReal[])
{
int choice;
Scanner sc = new Scanner(System.in);
System.out.println("1.display mark");
System.out.println("2.exit");
choice = sc.nextInt();
while (choice !=2 && choice != 1)
{
System.out.println("invalid input enter again");
choice = sc.nextInt();
}
switch (choice)
{
case 1:
output(arrayString, arrayReal);
break;
case 2:
System.out.println("exiting");
break;
default:
System.out.println("invalid choice choose between 1 and 2");
choice = sc.nextInt();
}
}
public static void output(String arrayString[], double arrayReal[])
{
String name;
Scanner sc = new Scanner(System.in);
for (int i=0;i<arrayString.length;i++)
{
System.out.println(arrayString[i]);
}
System.out.println("enter stident name");
name = sc.nextLine();
for (int k=0;k<arrayString.length;k++)
{
if(!arrayString.equals(name))
{
System.out.println("invalid name");
choice(arrayString, arrayReal);
}
}
for (int j=0;j<arrayString.length;j++)
{
if (arrayString[j].equals(name))
{
System.out.println("mark of " + arrayString[j] + "is " + arrayReal[j]);
}
}
im trying to validate the student name and if it doesnt equal to any of the names in the array return back to the menu. it does go back to the menu but the problem is after going back to the menu even if i type the correct student name if keps going back to the menu. i thought for loops were supposed to loop set amount of times and pass to the next code?? is that right? also is my approach correct? ive tried putting if else in the last for loop but that didnt end up as i wanted it to as well. any help is appreciated thanks!
EDIT-
thanks for spotting the mistake. fixed !arrayString.equals(name) to !arrayString[k].equals(name) but still the same problem
Your problem ist here:
for (int k=0;k<arrayString.length;k++)
{
if(!arrayString.equals(name))
{
System.out.println("invalid name");
choice(arrayString, arrayReal);
}
}
You are comparing an Array String[] arrayString with a String name. They are never going to be treated as equal and therefor your choice method is allways called.
Also the whole loop is totally pointless as you never use your loop index k for anything.
You don't need a loop here at all. Instead you can simply convert the String array to a temporary list and check if it contains your input:
if(!Arrays.asList(arrayString).contains(name))
{
System.out.println("invalid name");
choice(arrayString, arrayReal);
}
Edit:
here a short main Method that can be used for testing:
public static void main(final String[] args) {
final String[] test = { "Mark", "Peter" };
final double[] test2 = { 1, 2 };
choice(test, test2);
}
Input/Output:
OUTPUT: 1.display mark
OUTPUT:2.exit
INPUT: 1
OUTPUT: Mark
OUTPUT: Peter
OUTPUT: enter stident name
INPUT: Mark
OUTPUT: mark of Markis 1.0
The logic at this part, after adding the index, is still wrong:
for (int k=0;k<arrayString.length;k++)
{
if(!arrayString[k].equals(name))
{
System.out.println("invalid name");
...
}
}
this will print "invalid name" for every name in the list that is not the given name. Example: if the first name in the array does not match, you will get a message (and choice called), no matter if the second entry matches.
One way is to search the whole array until you find the name and then act on the result:
boolean found = false;
for (int k=0;k<arrayString.length;k++)
{
if(arrayString[k].equals(name))
{
found = true;
break; // stop searching
}
}
if (!found)
{
System.out.println("invalid name");
choice(arrayString, arrayReal);
}

How do I use "stop" as a keyword to stop the for loop?

I want to set "numberOfItems" as a large number but want to stop the loop midway. I need help for the while part. No ArrayList please, I'm not familiar with that yet.
do
{
for(int i=0; i<=numberOfItems; i++)
{
System.out.println("Enter product name");
productName[i]=input.nextLine();
System.out.println("Enter price of product");
productPrice[i]=input.nextDouble();
System.out.printf("%s,%n,%.2f",productName[i],productPrice[i]);
}
}
while (! (productName[i]= input.nextLine("stop")));
You can put an if statement inside of your for loop to decide when to stop it; the instruction to stop a loop is break.
Note that this means you don't need the enclosing do loop.
Looking at how your code is working, the most sensible place to break is probably after entering a product name. This would mean you can't store a STOP product... I've left this as UPPERCASE (you can use equalsIgnoreCase if you don't care about case).
Something like this:
for(int i=0; i<=numberOfItems; i++)
{
System.out.println("Enter product name (or STOP to stop)");
String tmpProduct = input.nextLine();
//trim to avoid whitespace
if ("STOP".equals(tmpProduct.trim())) {
break; //we stop the loop here
}
//they didn't type STOP, guess they wanted a product.
productName[i]=tmpProduct;
System.out.println("Enter price of product");
productPrice[i]=input.nextDouble();
System.out.printf("%s,%n,%.2f",productName[i],productPrice[i]);
}
This also avoids the need for the outer loop. If you would rather ask after every product (this could get annoying after a while) then you can put the check and prompt after requesting the double.
for(int i=0; i<=numberOfItems; i++)
{
System.out.println("Enter product name");
//they didn't type STOP, guess they wanted a product.
productName[i]=input.nextLine();
System.out.println("Enter price of product");
productPrice[i]=input.nextDouble();
System.out.printf("%s,%n,%.2f",productName[i],productPrice[i]);
System.out.println("type STOP to stop or anything else to continue");
String tmp = input.nextLine();
//trim to avoid whitespace problems
if ("STOP".equals(tmp.trim())) {
break; //we stop the loop here
}
}
UPDATE This is enhanced answer explained in details
// this method to validate the input after reading the entire line
static public Object interpretedInput(String line){
if(line.replace(" ", "").equalsIgnoreCase("stop")){ // if stop detected
return null;
}
else {// if it's not stop
for(char c : line.toCharArray()){ // read every char in the line
if(!Character.isDigit(c) && c!='.'){ // if any non digit is detected that means it should be considered as a string
//(note if you want the product name to consist of digits only -> this won't work)
return line; // return line
}
}
}
try{return Double.valueOf(line);} // else try to parse the line to extract the double value and return it
catch(NumberFormatException e){return null;}
}
Scanner input = new Scanner(System.in);
int numberOfItems = 10; // for example
String[]productName = new String[10];
double[] productPrice = new double[10];
for(int i=0; i<numberOfItems; i++){
System.out.println("Enter product name");
Object theInput = interpretedInput(input.nextLine()); // the method will return either null or string or double
if(theInput==null){ // if it's null that means to stop
break;
}
else if (theInput instanceof String){ // if it's instance of string accept it
productName[i]=(String)theInput;
}
while(!(theInput instanceof Double)){ // this will repeat until a valid double input is entered
//then it will assign it and display the content
System.out.println("Enter price of product");
theInput = interpretedInput(input.nextLine());
if(theInput==null){
i=numberOfItems; // to terminate the parent for loop as well
break;
}
else if (theInput instanceof Double){
productPrice[i]=(Double)theInput;
System.out.printf("%s, %.2f\n",productName[i],productPrice[i]);
}
else{System.out.println("Invalid Price");}
}
}

Searching text files to get specific double

I am writing a bank account program for my Comp Sci class, and need to search a .txt file for a account number a user enters (which is an int) and then pull out the next row which is the balance. i.e. the user enters the account #12345679 and i need to pull out the balance of it. Below is an example of the txt file
12345678
133.87
12345679
500.00
12345670
123.00
So far I have and I know that i'm going to have to put how to get the balance in the if statment
while (accountTries < 3)
{
System.out.println("Please enter your 8 digit account number");
accountNumber = console.next();
accountLength = accountNumber.length();
while (in.hasNextInt())
{
line = in.hasNextInt();
if (accountLength == 8 && line == accountNumber )
{
accountTries = 3;
}
}
System.out.println("INVALID ACCOUNT NUMBER.");
accountTries++;
}
}//End of while loop
Not sure what you're trying to do... but this doesn't seem right:
line = in.hasNextInt();
Shouldn't you be getting the value here? You're just testing to see if there's anything there, like you did in the "while" condition.
outer: while (accountTries < 3)
{
System.out.println("Please enter your 8 digit account number");
accountNumber = console.next();
accountLength = accountNumber.length();
while (in.hasNextLine())
{
line = in.nextLine();
result = in.nextLine();
if (accountLength == 8 && line.equals(accountNumber))
{
accountTries = 3;
break outer;
}
}
System.out.println("INVALID ACCOUNT NUMBER.");
accountTries++;
}
}//End of while loop
I used a labeled break to get out of the outer while (you can do the same with if statements and a done flag but I'm to lazy to do that here)
You can simply read file to String and split it by line separator(\n or \n\r).
For example :
String fileContent = //read String from file;
String[] elements = fileContent .split("\n");
for(int i =0; i< elements.length; i++){
if(i%2 ==0){
//get account number
}else{
//get balance
}
}

Categories