Do While loop not coordinating with a Scanner the 2nd time - java

I have a project that I need help with. I'm a beginner in programming, and I don't understand this. I'm hoping to get an answer.
Scanner reg_input = new Scanner(System.in);
int ctr = 0,item = 1;
char reg_mn = 'y', choice;
String[] user = new String[item];
String[] pass = new String[item];
reg_mn = 'y';
do {
System.out.println("[REGISTER]");
System.out.println("==========");
System.out.print("Username: ");
user[ctr] = reg_input.next(); //Line 11
System.out.print("Password: ");
pass[ctr] = reg_input.next();
System.out.println("==========");
System.out.println("Do you wish to Continue? [Y/N]");
choice = reg_input.next().charAt(0);
if (choice == 'y' || choice =='y') {
item = item + 1;
}
else if (choice == 'n' || choice == 'N') {
reg_mn = 'n';
item = item + 1;
return;
}
ctr++;
} while (reg_mn == 'y' || reg_mn == 'Y');
the 1st loop is fine. The problem here is when I type "y" to
try and get the 2nd loop, I get an error from the scanner at Line 11
I researched for problems like this but I seem to get dead ends, that or I haven't read it properly.

Because you have declared a string with the size of an item whose value is 1 initially.
So if you increment the item by 1 but the string array size would not be incremented because it is declared with size 1.
String[] user = new String[item];
String[] pass = new String[item];
Change like this
String[] user = new String[30];
String[] pass = new String[30];
You have to declare with some maximum size.
I suggest you use any java Collections for this like HashMap.
Because here you are declaring the string array with maximum size so it allocated that size however if you are storing only 2 users remaining size would be waste. For this use Collections.

Related

Stop duplicate input (scanner & arrays)

I'm fairly new at programming. Currently im working on a uni project to create a basic text game using java. The problem im having is trying to figure out how to implement a business rule that does not allow a user to enter the same name. I have it set up so the scanner reads into the array. I'm using Java and this is my first time using the forum so i greatly appreciate any help given and thank all of you in advance!:)
And apologies for the poor formatting i dont know how to post properly yet.
try {
// Takes in the number of players
int noOfPlayers;
Scanner s = new Scanner(System.in);
System.out.println("Enter number of players between 2 and 4");
noOfPlayers = s.nextInt();
s.nextLine();
if (noOfPlayers < 2 || noOfPlayers >= 5) { // limits number of players enter no less than 2 and no greater than 4
System.out.println("Nope wrong number");
enterInfo();
s.close();
return;
} else {
// array for storing player names
String[] names = new String[noOfPlayers];
// iterates through the array depending how many players are selected
// and takes in String input
for (int counter = 0; counter < noOfPlayers; counter++) {
System.out.println("Enter name of player : " + (counter + 1));
names[counter] = s.nextLine();
// fix this to stop same name sbeing entered
//if(names.equals(names)) {
// System.out.println("Enter a different name");
// counter--;
// }
}
}
s.close();
} catch (Exception e) {
System.out.println("Problem");
}
}
How about use Set? Set has to have all different things.
Like in Array [kim,lee,kim,park] but in Set [kim,lee,park]
input kim => Array [kim] set[kim] lenth 1 == size 1
input lee => Array [kim,lee] set[kim,lee] lenth 2 == size 2
input kim => Array [kim,lee,kim] set[kim,lee] lenth 3 != size 2
then all you have to do is tell them "make another name plz"
String name = s.nextLine();
names[counter] = name;
Set<String> set = new HashSet<String>();
set.add(name)
if(names.length != set.size())
{
System.out.println("Enter a different name");
counter--;
}
I hope you understand my poor explanation.

Replacing Position in Array Amongst Other Methods

Firstly - I thank anyone who takes the time to actually look at this since I feel like it's a rather annoying request.
I just completed a large challenge at the end of a series of Java 101 videos. The challenge is to design a guest list method ( as in for a restaurant or a party ) and some features along with it. This is really the first time I've written anything with multiple methods.
As the final step in this challenge, I need to design a method that allows the user to insert a new guest at a certain position while not removing any other guests. In other words, inserting a new guest and shifting the remaining guests downwards by a single index.
The issue I have is that the new guest is always inserted not only for the position I want, but also the position one after. It inserts itself twice and ends up over-writing the previous guest in the process.
import java.util.Scanner;
import java.io.*;
import java.lang.*;
import java.util.*;
public class GuestList_Edited {
public static void main(String[] args) {
// Setup for array, setup for scanner
String[] guests = new String[11];
Scanner scanner = new Scanner(System.in);
// A method to put these here so we don't always have to add guests. This method automatically inserts five guests into the guest list.
InsertNames(guests);
// Do-while loop to make sure that this menu screen shows up every time asking us what we want to do.
// It also makes certain that the menu shows up when we initially run the program.
do {
displayMenu(guests);
// This must remain in main for the rest of the program to reference it.
int option = getOption();
// If loop that will allow people to add guests
if (option == 1) {
addGuest(guests);
} else if (option == 2) {
RemoveGuest(guests);
} else if (option == 3) {
RenameGuest(guests);
} else if (option == 4) {
insertGuest(guests);
} else if (option == 5) {
System.out.println("Exiting...");
break;
}
} while (true);
}
// This displays the starting menu
public static void displayMenu(String SentArr[]) {
System.out.println("-------------");
System.out.println(" - Guests & Menu - ");
System.out.println();
GuestsMethod(SentArr); // Makes all null values equal to --
System.out.println();
System.out.println("1 - Add Guest");
System.out.println("2 - Remove Guest");
System.out.println("3 - Rename guest");
System.out.println("4 - Insert new guest at certain position");
System.out.println("5 - Exit");
System.out.println();
}
// This prints all the guests on the guest list and also adjusts the guest list when a guest is removed
public static void GuestsMethod(String RecievedArr[]) {
// If loop which prints out all guests on the list.
// "Null" will be printed out for all empty slots.
for (int i = 0; i < RecievedArr.length - 1; i++) {
// Make all null values and values after the first null value shift up in the array.
if (RecievedArr[i] == null) {
RecievedArr[i] = RecievedArr[i + 1];
RecievedArr[i + 1] = null;
}
// Make all null's equal to a string value.
if (RecievedArr[i] == null) {
RecievedArr[i] = " ";
}
// If values are not equal to a blank string value, assign a number.
if (RecievedArr[i] != " ") {
System.out.println((i + 1) + ". " + RecievedArr[i]);
}
// If the first value is a blank string value, then print the provided line.
if (RecievedArr[0] == " ") {
System.out.println("The guest list is empty.");
break;
}
}
}
// I've really got no idea what this does or why I need a method but the course I'm taking said to create a method for this.
// It gets the desired option from the user, as in to add a guest, remove a guest, etc.
static int getOption() {
Scanner scanner = new Scanner(System.in);
System.out.print("Option: ");
int Option = scanner.nextInt();
return Option;
}
// Allows users to add guests
public static String[] addGuest(String AddArr[]) {
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < AddArr.length; i++) {
// The below if statement allows the program to only ask for a name when a given space is "null", meaning empty.
if (AddArr[i] == " ") {
// so the loop runs until it hits a null value.
System.out.print("Name: ");
AddArr[i] = scanner.nextLine();
// Then that same value which was null will be replaced by the user's input
break;
}
}
return AddArr;
}
public static String[] RemoveGuest(String RemoveArr[]) {
Scanner scanner = new Scanner(System.in);
System.out.print("Number of guest: ");
int input = scanner.nextInt();
int number = input - 1;
// While loop to look for numbers that fit within array's range
while (number < -1 || number > 9) {
System.out.println("Trying to pull a fast one? No more funny games, give me a real number to work with.");
System.out.println(" ");
System.out.println("What is the number of the guest");
input = scanner.nextInt();
number = input - 1;
}
for (int i = 0; i < RemoveArr.length; i++) {
if (RemoveArr[number] != null) {
RemoveArr[number] = null;
break;
}
}
return RemoveArr;
}
// This inserts names into the array so we don't have to add guests everytime.
public static String[] InsertNames(String InsertNames[]) {
InsertNames[0] = "Jacob";
InsertNames[1] = "Edward";
InsertNames[2] = "Rose";
InsertNames[3] = "Molly";
InsertNames[4] = "Christopher";
// guests[5] = "Daniel";
// guests[6] = "Timblomothy";
// guests[7] = "Sablantha";
// guests[8] = "Tagranthra";
return InsertNames;
}
public static String[] RenameGuest(String RenamedGuests[]) {
Scanner scanner = new Scanner(System.in);
System.out.print("Number of guest: ");
int input = scanner.nextInt();
int number = input - 1;
// While loop to look for numbers that fit within array's range
while (number < -1 || number > 9) {
System.out.println("Trying to pull a fast one? No more funny games, give me a real number to work with.");
System.out.println(" ");
System.out.println("What is the number of the guest");
input = scanner.nextInt();
number = input - 1;
}
for (int i = 0; i < RenamedGuests.length; i++) {
if (RenamedGuests[number] != null) {
RenamedGuests[number] = null;
System.out.println("What would you like the guest's name to be?");
String NewName = scanner.next();
RenamedGuests[number] = NewName;
break;
}
}
return RenamedGuests;
}
// The final method which I am struggling with.
public static String[] insertGuest(String NewPositionArray[]) {
Scanner scanner = new Scanner(System.in);
System.out.print("Number: ");
int num = scanner.nextInt();
scanner.nextLine();
if (num >= 1 && num <= 10 && NewPositionArray[num - 1] != null)
System.out.print("Name: ");
String name = scanner.nextLine();
for (int i = 10; i > num - 1; i--) {
NewPositionArray[i] = NewPositionArray[i - 1];
NewPositionArray[num - 1] = name;
}
if (num < 0 || num > 10) {
System.out.println("\nError: There is no guest with that number.");
}
return NewPositionArray;
}
}
Once again, thanks. I realize I've probably done 1000 things wrong here. I appreciate your consideration.
I recommend you to declare ArrayList object instead of the normal array declaration; to avoid heavy work on the code where you can add an element into the ArrayList object with predefined add(int position, an element with your data type) method in a specific position and the ArrayList automatically will shift the rest elements to the right of it.
and for several reasons.
for more info about ArrayList in Java, please look at: -
Array vs ArrayList in Java
Which is faster amongst an Array and an ArrayList?
Here an example of add() method; which inserts the element in a specific position: -
Java.util.ArrayList.add() Method

adding values to an array using counter

I've been learning java for the last 1.5 month. Now the instructor has asked us to create a program that take the name and phone number (but in a method) from the user until the user enters "E". The program should then print all the information stored in the all the arrays.
The program has a main menu and the user will enter "1" to create an account (name and phone number) and then the main menu appears again and the user create another account and so on and so forth... until he chooses another option from the menu or enter "E" to exist and print the summary for all the accounts.
My problem is that I tried to create a counter as a references to each account spot in the arrays(index in array); so after each time the user enters a name and a number the counter add 1 and the arrays index add 1 and moves to the next spot… but that didn't work.
I didn't complete the code, stopped at choice 1 to test the create account method
public static void addDonor(String[] a1, String[] a2, char[] a3, int[] a4, int [] a5){
Scanner input = new Scanner(System.in);
System.out.print(" Enter the name (first and last):" + " ");
String name = input.nextLine();
System.out.print(" Enter Mobile No.:" + " ");
String phone = input.next();
if (phone.length() < 10 && phone.startsWith("0") == false){
while (true){
System.out.println("Wrong Mobile NO... try again!");
System.out.print(" Enter Mobile No.:" + " ");
phone = input.next();
if (phone.length() > 10 || phone.startsWith("0") == true)
break;
}
}
System.out.print(" Enter Blood Group Type (A, B or O):" + " ");
char blood = input.next().charAt(0);
while (blood != 'a' || blood != 'b' || blood != 'c'){
System.out.println("Wrong Blood Group Type... try again!");
System.out.println(" Enter Blood Group Type (A, B or O):" + " ");
blood = input.next().charAt(0);
if (blood == 'A' || blood == 'B' || blood == 'O')
break;
}
int counter = 0;
a1[counter] = name;
a2[counter] = phone;
a3[counter] = blood;
a4[counter] = 1;
a5[counter] = 1;
counter++;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String[] Name = new String[20];
String[] Mobile = new String[20];
char[] Blood_Gp = new char[20];
int[] Count_o_Donation = new int[20];
int[] Blood_Stock = new int[20];
while (true){
displayMainMenu();
readAndVerify();
String choice = readAndVerify();
switch (choice){
case "1":
addDonor(Name, Mobile, Blood_Gp, Count_o_Donation, Blood_Stock);
break;
}
if (choice.equals("e"))
break;
}
System.out.println(Name[0]);
System.out.println(Name[1]);
}
The problem is thar you are creating the variable index inside the addDonor method. So everytime the method is invoked a new variable with value 0 is going to be created, that's why it's not moving. You should create the varible outside the method and pass it as parameter.
Something like this:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String[] Name = new String[20];
String[] Mobile = new String[20];
char[] Blood_Gp = new char[20];
int[] Count_o_Donation = new int[20];
int[] Blood_Stock = new int[20];
int index = 0;
while (true){
displayMainMenu();
readAndVerify();
String choice = readAndVerify();
switch (choice){
case "1":
addDonor(Name, Mobile, Blood_Gp, Count_o_Donation, Blood_Stock, index);
index++
break;
}
if (choice.equals("e"))
break;
}
System.out.println(Name[0]);
System.out.println(Name[1]);
}
public static void addDonor(String[] a1, String[] a2, char[] a3, int[] a4, int [] a5), int index{
Scanner input = new Scanner(System.in);
System.out.print(" Enter the name (first and last):" + " ");
String name = input.nextLine();
System.out.print(" Enter Mobile No.:" + " ");
String phone = input.next();
if (phone.length() < 10 && phone.startsWith("0") == false){
while (true){
System.out.println("Wrong Mobile NO... try again!");
System.out.print(" Enter Mobile No.:" + " ");
phone = input.next();
if (phone.length() > 10 || phone.startsWith("0") == true)
break;
}
}
System.out.print(" Enter Blood Group Type (A, B or O):" + " ");
char blood = input.next().charAt(0);
while (blood != 'a' || blood != 'b' || blood != 'c'){
System.out.println("Wrong Blood Group Type... try again!");
System.out.println(" Enter Blood Group Type (A, B or O):" + " ");
blood = input.next().charAt(0);
if (blood == 'A' || blood == 'B' || blood == 'O')
break;
}
a1[index] = name;
a2[index] = phone;
a3[index] = blood;
a4[index] = 1;
a5[index] = 1;
This isn't really a java question as much as it is a debug question. Your counter is local to the method it is in, so every time the method gets called the counter gets reset.
A variable has a scope. The scope of a variable depends on where you define it. Inside a method block (or inside the parameter section) a variable will live as long as the method block. If defined inside a class as non-static it will live as long as the instance. If defined as static inside a class it will live as long as the class (most of the time this means forever)
In your case you have 2 options: Either you make the variable static, define it outside of your addDonor method and pass it down into the addDonor method by value (so you cannot increment it inside addDonor, do this whereever you call addDonor).
If you go with the static variable then your code remains unchanged. Static variables generally are defined at the top of the class.
If you go with the passing variable down into addDonor then the main method becomes responsible for keeping and incrementing the counter variable. Make sure it only gets incremented on a succesful iteration.
There are other things you can do but they need you to know about Objects.
There are many mistakes here.
First of you should really gather all the information you need in a class. That way you could easily store it all in one array.
public class donor{
String name;
String mobile
...
}
Secondly since you don't know how many inputs you are getting and array is really a stupid way of storing it. If you use a list you can simply do:
List<Donor> donors = new ArrayList<>();
donors.add(donor);
If you need to use an array you could try to use a counter. I would probably do it something like this:
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String[] name = new String[20];
String[] mobile = new String[20];
char[] bloodGroup = new char[20];
int[] countODonation = new int[20];
int[] bloodStock = new int[20];
int counter = 0;
boolean continue = true;
while (continue){
displayMainMenu();
String choice = readAndVerify();
switch (choice){
case "1":
name[counter] = readName();
...
counter++;
break;
}
if (choice.equals("e"))
continue = false;
}
}
But once again you should really use a class for the donor stuff. And a list.

Replacing a String statment that's being used by a constructor

So I'm working on a project to count the number of vowels and consonants of a desired string. I've got almost everything working, but I can't seem to get the option to replace the string with a new one to work properly. I think it's a problem with having the new choice be applied to the Driver construct but I can't seem to figure out a way to do that without breaking the program.
import java.util.*;
public class Driver{
private String entry;
int vowels = 0;
int cons = 0;
public Driver(String input){
entry = input;
this.count();
}
public boolean isVowel(char x){
return (x == 'A' || x == 'E' || x == 'I' || x == 'O' || x == 'U' ||
x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u');
}
public boolean isConsonant(char x){
return (((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z')) && !isVowel(x));}
public int getVowels(){
return vowels;
}
public int getConsonants(){
return cons;
}
public void count(){
int l = entry.length();
for(int i = 0; i < l; i++){
if(this.isVowel(entry.charAt(i))){
vowels++;
}else{
if(this.isConsonant(entry.charAt(i))){
cons++;
}
}
}
}
static Scanner kb = new Scanner(System.in);
public static void main(String[] args){
int choice; //Choice from menu
int vowels = 0; //# of vowels in entry
int cons = 0; //# of consonants in entry
String entry; //User's input
System.out.print("Enter a string:");
entry = kb.nextLine();
do{
Driver sentence = new Driver(entry);
System.out.println("Enter a number");
System.out.println("1. Count the number of vowels in the string");
System.out.println("2. Count the number of consonants in the string");
System.out.println("3. Count both the vowels and consonants in the string");
System.out.println("4. Enter another string");
System.out.println("5. Exit the program:");
choice = kb.nextInt();
switch(choice){
case 1:
System.out.println("Vowels: " + sentence.getVowels());
break;
case 2:
System.out.println("Consonants: " + sentence.getConsonants());
break;
case 3:;
System.out.println("Vowels: " + sentence.getVowels() + "\nConsonants: " + sentence.getConsonants());
break;
case 4:
System.out.print("Enter a string:");
entry = kb.nextLine();
//Driver sentence = new Driver(entry);
break;
default:
System.out.println("Please enter a value input: ");
}
}while(choice != 5);
}
}
You should have the Driver Class on its own (without the main() method).
Then create another Class that will be your startup Class which will contain the main() method). For the sake of argument let's call it VowelsAndConsonants.
The problem that's causing all the grief is your keyboard entry of 1 to 5 for the Console menu. You are using the Scanner.nextInt() method which is okay as long as you know that the whatever is entered is not all consumed and remains within the Scanner buffer and this is because the Scanner.nextInt() method doesn’t read and consume the line separator that is applied when the Enter Key is hit. So, when Scanner.nextLine() is used as the next Scanner method the first thing it gets hold of is that line separator that's held within the Scanner buffer which in turn is just like hitting the Enter key and therefore it skips what was typed. On the other hand the Scanner.nextLine() method does read in and consume the line separator. One way to get around this problem is to add (in your case) kb.nextLine(); directly after the choice = kb.nextInt(); code line. This forces the line separator to be consumed and empties the buffer. In essence the menu would then look something like this:
Driver sentence = new Driver(entry);
do {
System.out.println("Enter a Menu choice (1 to 5): ");
System.out.println("1. Count the number of vowels in the string");
System.out.println("2. Count the number of consonants in the string");
System.out.println("3. Count both the vowels and consonants in the string");
System.out.println("4. Enter another string");
System.out.println("5. Exit the program:");
choice = kb.nextInt();
kb.nextLine(); // Consume
..... the rest of your do/while code .....
}
EDIT: Based on your Question in Comment: "I'm curious as to why
there is a difference in how the line separator is dealt with tho. Is
this just something that is in Java, or is there a reason that it
isn't consumed from nextInt()?"
The Scanner Class is quite involved. It is by design that the nextInt() does this since Scanner can work based on tokens. You can use nextInt() to accept multiple numbers on a single input using (for example) a whitespace delimiter and then with the Scanner.hasNextInt() or Scanner.hasNext() methods in conjuction with the Scanner.nextInt() you can individually acquire each value, for example:
Scanner kb = new Scanner(System.in).useDelimiter(" *");
System.out.println("Enter numbers delimited with a white-space: ");
while (kb.hasNextInt()) {
int x = kb.nextInt();
System.out.println(x);
}
If you were to run this code and at the prompt enter on one line:
2 4 6 8 10
(note the whitespace between numbers) you will see a display within the Console window of:
2
4
6
8
10
Through each iteration of the while loop x would equal the next integer token from the line of numbers entered. This sort of thing however is best suited for reading numbers from a text file which Scanner can do as well. Read up on the Scanner Class.

Using || in while loop makes it take too many input values

public class MetricConversion {
public static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
String masses = "null";
String volumes = "null";
String temps = "null";
String lengths = "null";
int answer1 = 0;
String[] options = {"Mass = 1","Temperature = 2","Length = 3","Volume = 4"};
System.out.println("What would you like to convert?");
for(int i = 0;i<options.length;i++)
System.out.println(options[i]);
while(!input.hasNextInt() || input.nextInt() > options.length)
{
String garbage = input.nextLine();
System.out.println("That input is not valid, try again");
}
answer1 = input.nextInt();
input.nextLine();
The problem I am having is that the
while(!input.hasNextInt() || input.nextInt() > options.length)
is taking 2 valid inputs instead of 1 in order to make
answer1 = input.nextInt();
For example, when entering an invalid input it correctly prints my error message, but when entering a valid input I have to enter it twice in order to break the loop. However if I use the while loop without the || it only takes one value like it's supposed to.
You're consuming the value without assigning it to a variable. You can assign it within the loop condition like this:
while(!input.hasNextInt() || (answer1 = input.nextInt()) > options.length)
You are consuming scanner argument in while loop:
while(!input.hasNextInt()){
int argument = input.nextInt();
if(argument > options.length){
System.out.println("That input is not valid, try again");
continue; // get back to the start
}
// correctly handle your argument
}

Categories

Resources