arrays in arrays weird thing? Java - java

I have a variable B that stores how many user objects have been added in the array userarr. I'm using one line of code that adds a note that the user types in to the B element user object in the userarr array. Here it is:
userarr[login].notes[b] = tempnote;
tempnote is a string variable that temporarily holds the note the user types in, and login stores the user number that you are logged in to. So it assigns the string variable tempnote to the login value user object in the user array, and in element b element in the notes array for that user.
But for some reason there is a problem with this line of code.
I know it is that line of code, because it happens right after you confirm you want to add that note, and there is a println right next to it that never appears.
Here is the method for the whole note thing:
public static void loggedin() {
System.out.println("welcome, " + userarr[login].username + "!");
do{
System.out.println("type 'notes' to list current notes, type 'new' to add notes, type 'delete' to delete a note, or type 'exit' to exit the program.");
switch(scan.nextLine()){
case "exit":
System.out.println("exiting");
login = -1;
break;
case "delete":
break;
case "new":
System.out.println("\n\nType the note.");
String tempnote = scan.nextLine();
System.out.println("note is is now " + tempnote + ". is this what you want? type 'yes' to proceed, or 'no' to enter note again.");
String ch5 = scan.nextLine();
if (ch5.equals("no")) {
break;
} else {
userarr[login].notes[b] = tempnote;
System.out.println("note created!");
b += 1;
}
break;
case "notes":
for (int i=0;i<b;i++) {
System.out.println("Note " + i + ":");
System.out.println(userarr[login].notes[i] + "\n");
}
break;
default:
System.out.println("restarting.");
};
}while(login != -1);
}
Here is the user object thing:
static class user extends TextGame {
String username;
int password;
String[] notes;
public user(String username, int password) {
this.username = username;
this.password = password;
}
}
static user[] userarr = new user[10];
static int a = 0;
static int b = 0;
static int login = -1;
There is no error before i run it. when i get to the part that has the problem it says:
Exception in thread "main" java.lang.NullPointerException
at text.game.TextGame.loggedin(TextGame.java:80)
at text.game.TextGame.login(TextGame.java:53)
at text.game.TextGame.main(TextGame.java:135)
anyone know the problem?
EDIT: It seems necessary to show the whole class, because there is apparently a lot more information people need to know. So here is the whole thing for you to have all the information you need:
package text.game;
import java.util.Scanner;
public class TextGame {
static Scanner scan = new Scanner(System.in);
static class user extends TextGame {
String username;
int password;
String[] notes;
public user(String username, int password) {
this.username = username;
this.password = password;
}
}
static user[] userarr = new user[10];
static int a = 0;
static int b = 0;
static int login = -1;
public static void newuser() {
System.out.println("\n\nType the username for this user.");
String usernameA = scan.nextLine();
System.out.println("Username is now " + usernameA + ". is this what you want? type 'yes' to proceed, or 'no' to enter username again.");
if (scan.nextLine().equals("no")) {
newuser();
} else {
System.out.println("\n\n type the password for this user. (numbers only.)");
int passwordA = scan.nextInt();
System.out.println("user is " + usernameA + " and password is " + passwordA + ". creating user.");
userarr[a] = new user(usernameA, passwordA);
System.out.println("user created!");
a += 1;
}
}
public static void login() {
System.out.println("which account do you want to log into? type the name of a user, or type 'list' to view the users signed in.");
String ch2 = scan.nextLine();
if (ch2.equals("list")){
for (int i=0;i<a;i++) {
System.out.println(userarr[i].username);
}
} else {
for (int i=0;i<a;i++) {if ((userarr[i].username).equals(ch2)){
System.out.println("type the password for this account (USE NUMBERS ONLY).");
int ch4 = scan.nextInt();
if (ch4==userarr[i].password) {
System.out.println("logged in!"); login = i; loggedin();
}else{
System.out.print("incorrect password!");
}
}
}
}
}
public static void loggedin() {
System.out.println("welcome, " + userarr[login].username + "!");
do{
System.out.println("type 'notes' to list current notes, type 'new' to add notes, type 'delete' to delete a note, or type 'exit' to exit the program.");
switch(scan.nextLine()){
case "exit":
System.out.println("exiting");
login = -1;
break;
case "delete":
break;
case "new":
System.out.println("\n\nType the note.");
String tempnote = scan.nextLine();
System.out.println("note is is now " + tempnote + ". is this what you want? type 'yes' to proceed, or 'no' to enter note again.");
String ch5 = scan.nextLine();
if (ch5.equals("no")) {
break;
} else {
userarr[login].notes[b] = tempnote;
System.out.println("note created!");
b += 1;
}
break;
case "notes":
for (int i=0;i<b;i++) {
System.out.println("Note " + i + ":");
System.out.println(userarr[login].notes[i] + "\n");
}
break;
default:
System.out.println("restarting.");
};
}while(login != -1);
}
public static void main(String[] args) {
do {
System.out.println("Welcome to LINCOLN COMP console OS. Type 'new' to create a new user, type 'log' to log in to an existing user, or type 'exit' to leave.\nif you are asked a yes or no question, if you type something other than yes or no, it will default to yes.");
String ch1 = scan.nextLine();
switch (ch1) {
case "new":
if (a==2) {
System.out.println("maximum users have been created. type a username to delete that user, type list to list users, or type back to return.");
String ch3 = scan.nextLine();
if (ch3.equals("list")) {
for (int i=0;i<a;i++) {
if (userarr[i].username==null) {
System.out.println("undefined");
}else{
System.out.println("\n" + userarr[i].username);
};
}
} else if (ch3.equals("back")) {
break;
} else {
for (int i=0;i<a;i++) {
if ((userarr[i].username).equals(ch3)){
System.out.println("type the password for this account (USE NUMBERS ONLY).");
int ch4 = scan.nextInt();
if (ch4==userarr[i].password) {
a --;
userarr[i] = null;
System.out.println("user deleted!");
break;
}else{
System.out.println("incorrect password.");
break;
}
}else if (i==a-1) {
System.out.println("user not found.");
break;
}
}
}
}else {
System.out.println("Initializing user creation method:");
newuser();
}
break;
case "log":
login();
break;
case "exit":
System.out.println("Goodbye!");
System.exit(0);
break;
case "debug":
for (int i=0;i<userarr.length;i++) {
System.out.println(userarr[i]);
}
break;
default:
System.out.println("restarting.");
}
} while (true);
}
}//Note from other user - Extra bracket?

Change
String[] notes;
to something like:
String[] notes = new String[10];

I noticed that you don't appear to be checking if there are next lines/ints whenever you use your scanner's next functions.
Take these two lines from your code for example...
String ch2 = scan.nextLine();
int ch4 = scan.nextInt();
You can check if there is indeed a next int, or next line by using the hasNext functions...
String ch2; //Declared outside of the if-statement for scope reasons
if(scan.hasNextLine()){
//the hasNext functions return true if there is a next line (or int for hasNextInt).
ch2 = scan.nextLine();
}else{
//if something needs to be done in the event that there is no nextLine, do it here
}
int ch4;
if(scan.hasNextInt()){
ch4 = scan.hasNextInt();
}else{
//if something needs to be done in the event that there is no nextInt, do it here
}
This might not solve your issue; however, this at least can prevent many potential issues later. You should always be sure there is more content to get before you get it, and using the hasNext functions make it very easy.
See more at https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

Related

Professor gets a java.io.FileNotFoundException but I don't?

I had a project for my Java class where the user enters patients for a hospital then the program reads a file and the user can choose to amend their added patients to the file, print it out to the screen, or both. The program works perfectly in NetBeans for me but in the professor's comments, he says his compiler got a FileNotFoundException(Edit: It is actually a runtime error), even though I included the file in the package. When I emailed him, he only repeated that he received a FileNotFoundException.
Here is the code:
package realworldproblem3;
import java.util.*;
import java.io.*;
public class xyzHospital {
static int numOfPat;
static Scanner input = new Scanner(System.in);
static String inp;
static ArrayList<Patient> p = new ArrayList<>();
public static void main(String[] args) throws IOException {
boolean done = false;
importPatients();
System.out.print("Add new patients to the report:\n");
while (done == false){
addPatient();
System.out.print("Are you done adding patients? (Y or N)\n");
inp = input.nextLine();
switch (inp.toLowerCase()){
case "y": done = true;
break;
case "n": done = false;
break;
default: System.out.print("You did not enter a valid character. The program will print results then exit.\n\n");
done = true;
break;
}
}
printAll();
}
static public void addPatient(){
numOfPat++;
Patient pat = new Patient();
p.add(pat);
pat.addInfo(numOfPat);
}
static public void printAll() throws IOException{
System.out.print("Do you want to output the report to the screen ('S'), to a file ('F'), or both('B')?\n");
inp = input.next();
PrintWriter writer = new PrintWriter("XYZHospitalExampleData-1.txt");
switch (inp.toLowerCase()){
case "s":
System.out.print("\t\t\t\t\tXYZ Community Hospital\t\t\n=============================================================================================================\n");
System.out.printf("%-14s%30s%38s%n", " Name", "Address", "Payment Information");
System.out.printf("%-8s%-8s%15s%10s%10s%8s%15s%15s%15s %n", "Last", "First", "Address Line 1", "City", "State", "Zip", "Payment Date", "Payment Amt.","Amount Owed");
System.out.print("=============================================================================================================\n");
for(int i = 0; i<numOfPat;i++){
p.get(i).print();
}
break;
case "f":
writer.print(""); //writes over file so there is no duplicate patients
writer.close();
for(int i = 0; i<numOfPat;i++){
p.get(i).printToFile();
}
break;
case "b":
System.out.print("\t\t\t\t\tXYZ Community Hospital\t\t\n=============================================================================================================\n");
System.out.printf("%-14s%30s%38s%n", " Name", "Address", "Payment Information");
System.out.printf("%-8s%-8s%15s%10s%10s%8s%15s%15s%15s %n", "Last", "First", "Address Line 1", "City", "State", "Zip", "Payment Date", "Payment Amt.","Amount Owed");
System.out.print("=============================================================================================================\n");
writer.print("");
writer.close();
for(int i = 0; i<numOfPat;i++){
p.get(i).printToFile();
p.get(i).print();
}
break;
}
}
//each patient from the file is added as a patient object
static public void importPatients() throws IOException{
try(Scanner read = new Scanner(new BufferedReader(new FileReader("XYZHospitalExampleData-1.txt")))) {
while(read.hasNextLine()){ //one more line means that there is another patient to add
numOfPat++;
read.nextLine();
}
read.close();
try(Scanner r = new Scanner(new BufferedReader(new FileReader("XYZHospitalExampleData-1.txt")))) {
for (int j=0; j < numOfPat; j++){
String line = r.nextLine();
Patient pat = new Patient();
p.add(pat);
String[] str = line.split("\\^"); //the delimiter ^ is used to separate information in the file
for (int i = 0; i < str.length; i++){
if(str[i].isEmpty()||str[i].matches("0")||str[i] == null){ //if str[i] is empty, that means that it will be skipped over
i++;
}
switch (i){
case 0: p.get(j).ID = Integer.parseInt(str[i]);
break;
case 1: p.get(j).nameLast = str[i];
break;
case 2: p.get(j).nameFirst = str[i];
break;
case 3: p.get(j).address = str[i];
break;
case 4: p.get(j).opAddr = str[i];
break;
case 5: p.get(j).city = str[i];
break;
case 6: p.get(j).state = str[i];
break;
case 7: p.get(j).zip = Integer.parseInt(str[i]);
break;
case 8: p.get(j).optZip = Integer.parseInt(str[i]);
break;
case 9: p.get(j).payDate = str[i];
break;
case 10: p.get(j).payment = Double.parseDouble(str[i]);
break;
case 11: p.get(j).owed = Double.parseDouble(str[i]);
break;
default: System.out.print("Error.\n");
break;
}
}
}
r.close();
}
}
}
}
Here is the patient class:
package realworldproblem3;
import java.util.*;
import java.io.*;
public class Patient {
Scanner input = new Scanner(System.in);
String nameFirst, nameLast, address, opAddr,city, state, payDate;
int zip, optZip, ID;
double owed, payment;
public void print() {
System.out.printf("%-8s%-9s%-20s%-10s%-8s%-7s%-15s%-11.2f%-10.2f%n", nameLast, nameFirst, address, city, state, zip, payDate, owed, payment);
}
public void printToFile()throws IOException{
try (PrintWriter writer = new PrintWriter(new FileWriter("XYZHospitalExampleData-1.txt", true))) {
writer.write(ID + "^" + nameLast+ "^" + nameFirst + "^" + address + "^" + opAddr + "^" + city + "^" + state + "^" + zip + "^" + optZip + "^"+ payDate + "^" + payment + "^" + owed +"\n");
writer.close();
}
}
private void setName(){
System.out.print("Enter patient's first name.\n"); //user is asked for all information
nameFirst = input.nextLine(); //first three inputs use nextLine so it consumes the end of line character, so the address will be put in the string correctly.
System.out.print("Enter patient's last name.\n"); //if next() is used, the address is cut off at the first whitespace and the other elements of the address
nameLast = input.nextLine(); //are stored in the upcoming inputs.
if (nameFirst.isEmpty()||nameLast.isEmpty()){
System.out.print("You must enter the first and last name.\n");
setName();
}
}
public String getName(){
return nameFirst + " " + nameLast;
}
private void setAddr(){
System.out.print("Enter patient's address.\n");
address = input.nextLine();
if (address.isEmpty()){
System.out.print("You must enter the patients address.\n");
setAddr();
}
}
public String getAddr(){
return address;
}
private void setCity(){
System.out.print("Enter patient's home city.\n");
city = input.nextLine();
if(city.isEmpty()){
System.out.print("You must enter the patients city.\n");
setCity();
}
}
public String getCity(){
return city;
}
private void setState(){
System.out.print("Enter patient's state.\n");
state = input.nextLine();
if(state.isEmpty()){
System.out.print("You must enter the patients state.\n");
setState();
}
}
public String getState(){
return state;
}
private void setDate(){
System.out.print("Enter the payment date.\n");
payDate = input.next();
if(payDate.isEmpty()){
System.out.print("You must enter a payment date.\n");
setDate();
}
}
public String getDate(){
return payDate;
}
private void setZip(){
System.out.print("Enter patient's zipcode.\n");
try{
zip = input.nextInt();
}
catch(Exception e){
System.out.print("You must enter a valid 5-digit zipcode.\n");
input.next();
setZip(); //if it says that the setZip call will make the function loop infinitely, it is just a warning, it will not loop infinitely.
}
int length = String.valueOf(zip).length();
if(length != 5 && zip > 0){
System.out.print("You must enter a valid 5-digit zipcode.\n");
setZip();
}
}
public int getZip(){
return zip;
}
private void setOwed(){
System.out.print("Enter patient's due balance.\n");
try{
owed = input.nextDouble();
}
catch(Exception e){
System.out.print("Amount has to be a non-negative number.\n");
input.next();
setOwed();
}
int length = String.valueOf(owed).length();
if (owed <0 || length == 0){
System.out.print("Amount has to be a non-negative number.\n");
setOwed();
}
}
public double getOwed(){
return owed;
}
private void setPayment(){
System.out.print("Enter patient's payment amount.\n");
try{
payment = input.nextDouble();
}
catch(Exception e){
System.out.print("Payment amount has to be a positive number less than the amount owed.\n");
input.next();
setPayment();
}
int length = String.valueOf(payment).length();
if(payment < 0 || length ==0 || payment > owed){
System.out.print("Payment amount has to be a positive number less than the amount owed.\n");
setPayment();
}
}
public double getPayment(){
return payment;
}
private void setID(int Id){
ID = Id;
}
public int getID(){
return ID;
}
public void addInfo(int ID){
setID(ID);
setName();
setAddr();
setCity();
setState();
setZip();
setOwed();
setPayment();
setDate();
}
}
And here is the file XYZHospitalExampleData-1.txt:
12345^Jones^John^1234 Test Drive^PO box 123^Test City^IN^11234^1234^12/05/2015^250.0^25000.0
12346^Jones^Sara^1234 Test Drive^PO box 123^Test City^IN^11234^1234^12/20/2017^50.0^50000.0
12347^Doe^John^1235 XYZ Drive^null^Test City^IN^11234^0^01/05/2016^350.0^56799.0
12348^Doe^Sara^1235 XYZ Drive^null^Test City^IN^11234^0^11/09/2017^100.0^5020.52
12349^Lawson^Lonnie^12 South Drive^null^Test City^IN^11236^0^03/15/2013^253.51^25065.52
12349^Anderson^Sara^156 North Avenue^null^Test City^IN^11246^0^05/05/2013^21.33^251.56
12350^Smith^Andy^2455 East Street^null^Test City^IN^11246^0^12/05/2017^365.21^2543.33
It starts with their ID and ends with the amount that they owe. Any help to understand why my professor's compiler is giving him an error would be appreciated, and what I can do to be sure that it will be able to find the file so I do not have this problem again.
In the beginning of your main method you call importPatients which reads data from the XYZHospitalExampleData-1.txt file. If this file is not present, you'll get an exception (in the runtime, not a compiler error).
Most probably something went wrong when your package was unpackaged. Maybe the file was not copied to the expected location, something like that. One of the ways to address this would be to catch the FileNotFoundException and to display a message describing what went wrong and what is expected.

Creating a Basic Java phone book

I'm just learning Java and trying to make a simple phone book. For this part I'm trying to prompt the user to choose one of the 3 options below.
public class PhoneBook {
public static void main (String[] args){
options();
/*This method prompts the user to enter phone number
String s;
Scanner in = new Scanner(System.in);
System.out.println("Enter Phone Number");
s = in.nextLine();
System.out.println("You entered phone number ");
System.out.println(s);*/
}
public static void options (){
//This method gives the user choices on what to do
char choice;
char enterNumber = 'n';
char showNumber = 's';
char closeBook = 'c';
String read;
String freeLine = "error";
Scanner keyboard = new Scanner(System.in);
while (true){
System.out.println("Please select from the following");
System.out.println("n to Enter the number");
System.out.println("s to Show the number ");
System.out.println("c to Close the Phone book");
read = keyboard.nextLine();
choice = read.charAt(0);
switch (choice) {
case 'n': enterNumber;
system.out.println();
case 's':showNumber;
system.out.println();
case 'c': closeBook;
break;
default: System.out.println("Invalid Entry");
}
}
}
}
When I compile it i get errors on lines 37, 39, and 41 saying "Error: not a statement". I feel like something is missing. If anyone can help it would be greatly appreciated.
I am assuming that with the following lines you want to achieve to print the letter n for enterNumber in the console?
case 'n': enterNumber;
system.out.println();
This is not correct Java syntax. You will have to pass the variable value to the System.out.println method call:
case 'n': System.out.println(enterNumber);
Also note that Java is case sensitive, so you have to spell System with a capital letter.
On a side note, you will want to break; after each of your case statements, otherwise the code of the following cases will be executed as well:
switch (choice) {
case 'n': System.out.println(enterNumber);
break;
case 's': System.out.println(showNumber);
break;
case 'c': System.out.println(closeBook);
break;
default: System.out.println("Invalid Entry");
}
you do not have to write variable after 'cast' statement.
Refer below code.
import java.util.Scanner;
public class PhoneBook {
public static void main (String[] args){
options();
/*This method prompts the user to enter phone number
String s;
Scanner in = new Scanner(System.in);
System.out.println("Enter Phone Number");
s = in.nextLine();
System.out.println("You entered phone number ");
System.out.println(s);*/
}
public static void options (){
//This method gives the user choices on what to do
char choice;
char enterNumber = 'n';
char showNumber = 's';
char closeBook = 'c';
String read;
String freeLine = "error";
Scanner keyboard = new Scanner(System.in);
while (true){
System.out.println("Please select from the following");
System.out.println("n to Enter the number");
System.out.println("s to Show the number ");
System.out.println("c to Close the Phone book");
read = keyboard.nextLine();
choice = read.charAt(0);
switch (choice) {
case 'n':
System.out.println();
case 's':
System.out.println();
case 'c':
break;
default: System.out.println("Invalid Entry");
}
}
}
}
I have made a special answer for you. I don't add additional explanation. It's a large answer. I tell more than you ask, but I've done my best to make a readable code, so that you can analyse step-by-step to understand what you need at least when trying to make a Phone Book (console test drive application). If you need more explanation, write under comments.
First make a PhoneEntry class:
import java.util.Objects;
public class PhoneEntry implements Comparable<PhoneEntry> {
// https://jex.im/regulex/#!embed=false&flags=&re=%5E%5Ba-zA-Z%5D%7B2%2C%7D((-%7C%5Cs)%5Ba-zA-Z%5D%7B2%2C%7D)*%24
private static final String NAME_PATTERN = "^[a-zA-Z]{2,}((\\-|\\s)[a-zA-Z]{2,})*$";
// https://jex.im/regulex/#!embed=false&flags=&re=%5E%5C%2B%3F%5Cd%2B((%5Cs%7C%5C-)%3F%5Cd%2B)%2B%24
private static final String NUMBER_PATTERN = "^\\+?\\d+((\\s|\\-)?\\d+)+$"; //^\+?\d+((\s|\-)?\d+)+$
private final String name;
private final String number;
public PhoneEntry(String name, String number) {
if (!name.matches(NAME_PATTERN) || !number.matches(NUMBER_PATTERN)) {
throw new IllegalArgumentException();
}
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public String getNumber() {
return number;
}
public boolean nameContainsIgnoreCase(String keyword) {
return (keyword != null)
? name.toLowerCase().contains(keyword.toLowerCase())
: true;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof PhoneEntry)) {
return false;
}
PhoneEntry phoneEntry = (PhoneEntry) obj;
return name.equalsIgnoreCase(phoneEntry.name)
&& number.equalsIgnoreCase(phoneEntry.number);
}
#Override
public int hashCode() {
int hash = 5;
hash = 17 * hash + Objects.hashCode(this.name.toLowerCase());
hash = 17 * hash + Objects.hashCode(this.number.toLowerCase());
return hash;
}
#Override
public int compareTo(PhoneEntry phoneEntry) {
return name.compareToIgnoreCase(phoneEntry.name);
}
}
Then the test drive
public class TestDrive {
private static final String choices = "nspc";
enum Choice {
CREATE, READ, PRINT, CLOSE;
static Choice getChoice(char c) {
switch (c) {
case 'n':
return Choice.CREATE;
case 's':
return Choice.READ;
case 'p':
return Choice.PRINT;
case 'c':
return Choice.CLOSE;
}
return null;
}
}
// Main
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
final Set<PhoneEntry> entries = new TreeSet<>();
Choice choice;
while ((choice = getChoice(kbd)) != Choice.CLOSE) {
switch (choice) {
case CREATE:
PhoneEntry entry = getPhoneEntry(kbd);
if (entry != null) {
entries.add(entry);
}
break;
case READ:
print(readEntries(entries, kbd));
break;
case PRINT:
print(entries);
break;
}
}
}
private static Choice getChoice(Scanner kbd) {
System.out.println("\nPlease select from the following");
System.out.println("\tn to Enter the number");
System.out.println("\ts to Show numbers by keyword ");
System.out.println("\tp to Show all numbers ");
System.out.println("\tc to Close the Phone book");
System.out.print("> ");
String input = kbd.nextLine();
Choice choice = null;
if (!input.isEmpty()
&& choices.contains(input.toLowerCase())
&& ((choice = Choice.getChoice(input.toLowerCase().charAt(0))) != null)) {
return choice;
}
System.out.println("ERR: INVALID ENTRY. TRY AGAIN");
return getChoice(kbd);
}
private static PhoneEntry getPhoneEntry(Scanner kbd) {
System.out.print("Type contact name: ");
String name = kbd.nextLine();
System.out.print("Type phone number: ");
String number = kbd.nextLine();
try {
return new PhoneEntry(name, number);
} catch (IllegalArgumentException ex) {
System.out.println("\nERR: WRONG ENTRY");
}
return null;
}
private static void print(Set<PhoneEntry> entries) {
System.out.println("\nPHONE NUMBERS\n");
entries.stream().forEach(entry -> {
System.out.printf("Name: %s%nPhone: %s%n%n",
entry.getName(), entry.getNumber());
});
}
private static Set<PhoneEntry> readEntries(Set<PhoneEntry> entries, Scanner kbd) {
System.out.print("Type keyword: ");
return entries.stream().filter(entry
-> entry.nameContainsIgnoreCase(kbd.nextLine()))
.collect(Collectors.toCollection(TreeSet::new));
}
}
Instead of enterNumber;, you have to write enterNumber();.
The parentheses mean: Call the method.

Scanner ignoring the String "name"

I am trying to take user input for name, last name, phone number and age.
For some odd reason the scanner is skipping name but none of the other variables.
Can someone point out my mistake please? I can't figure it out.
import java.util.Scanner;
public class Lab2{
String [][] info = new String [10][4];
public static void main(String [] args){
new Lab2();
}
public Lab2(){
Scanner input = new Scanner(System.in);
System.out.println();
System.out.println("Student contact Interface");
System.out.println("Please select a number from the options below:");
while(true){
System.out.println("1: Add a new contact.");
System.out.println("2: Remove an existing contact.");
System.out.println("3: Display the contact list.");
System.out.println("0: Exit the contact list.");
int options = input.nextInt();
String name, lastName, number, age;
switch(options){
case 1:
System.out.println("Please enter the name: ");
name = input.nextLine(); // This is the String var that is not accepting input from...
System.out.println("Please enter the last name: ");
lastName = input.nextLine();
System.out.println("Please enter the phone number: ");
number = input.nextLine();
System.out.println("Please enter the age (eg. 25): ");
age = input.nextLine();
addStudent(name, lastName, number, age);
break;
case 2:
System.out.println("\nEnter the name to remove: ");
String delName = input.nextLine();
System.out.println("\nEnter the last name to remove: ");
String delLastName = input.nextLine();
remove(delName, delLastName);
break;
case 3:
display();
break;
case 0:
System.out.println("Thank you for using the contact Database.");
System.exit(0);
}
}
}
public void addStudent (String name, String lastName, String number, String age){
boolean infoInserted = false;
for(int i = 0; i < 10; i++){
if(info[i][0] == null || info[i][0].equals(null)){
info[i][0] = name;
info[i][1] = lastName;
info[i][2] = number;
info[i][3] = age;
infoInserted = true;
break;
}
}
if(infoInserted){
System.out.println("\nContact saved.\n");
}
else{
System.out.println("\nYour database is full.\n");
}
}
public void remove(String delName, String delLastName){
boolean removed = false;
int i = 0;
for (i = 0; i < 10; i++) {
if (info[i][0] != null && !info[i][0].equals(null)) {
if (info[i][0].equals(delName) && info[i][1].equals(delLastName)) {
while (i < 9) {
info[i][0] = info[i + 1][0];
info[i][1] = info[i + 1][1];
info[i][2] = info[i + 1][2];
info[i][3] = info[i + 1][3];
i++;
}
info[9][0] = null;
info[9][1] = null;
info[9][2] = null;
info[9][3] = null;
removed = true;
break;
}
}
}
if (removed) {
System.out.println("Contact removed.");
}
else {
System.out.println("Contact was not found.");
}
}
public void display (){
for (int i = 0; i < 10; i++) {
if (info[i][0] != null && !info[i][0].equals(null)) {
System.out.println("Contact " + (i + 1)+ ":");
System.out.println("\t" + info[i][0]);
System.out.println("\t" + info[i][1]);
System.out.println("\tPhone Number:" + info[i][2]);
System.out.println("\tAge:" + info[i][3]);
}
}
}
}
Add a
input.nextLine();
after your
int options = input.nextInt();
This is because:
nextInt method does not read the last newline character (of your integer input)
that newline is consumed in the next call to nextLine
causing name 'to be skipped'
so you need to 'flush away' the newline character after getting the integer input
Another option:
Take in the entire line, using input.nextLine()
Get the integer value using Integer.parseInt() to extract the integer value
It is skipping name because , input.nextInt() wont go to next input line.
You can use
int option=Integer.parseInt(input.nextLine());
then it wont skip name.

Does my add method do too much work?

I'm new to programming and I keep making the mistake of having a method do too much work. My TA gave me some advice that I should aim to make a method reusable enough that I can use it in another program without having to really modify very much. This definitely helped me approach writing methods in a better way, but I'm worried that I might have made my "add" method too meaty. Should I split it up or is it technically doing "one thing" even though it's pretty chunky?
Here's my main class (the referenced classes are just basic templates that don't do anything special aside from having getters and setters so I won't bother posting them here):
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.Scanner;
enum ClassStanding{FRESHMAN,SOPHOMORE,JUNIOR,SENIOR,UNKNOWN,MASTERS_STUDIES,PHD_STUDIES};
enum Major{CS,CEG,EE,ISE,BME,ME,MET,UNKNOWN};
enum StudentType{UNDERGRADUATE,GRADUATE,UNDECLARED};
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
ArrayList<Student> studentList = new ArrayList<>();
int counter;
boolean continueInput;
int contCounter;
do {
do {
System.out.print("Please enter what you want to do-ADD, REMOVE, LIST, or SAVE: ");
switch (stdin.next().toLowerCase()) {
case "add": add(stdin, studentList); counter = 0; break;
case "remove": counter = 0; break;
case "list": counter = 0; break;
case "save": counter = 0; break;
default: System.out.println("Improper input, please enter only ADD, REMOVE, LIST, or SAVE."); counter = 1;
}
} while (counter == 1);
do {
System.out.print("\nDo you want to continue? Yes or no: ");
switch (stdin.next().toLowerCase()) {
case "yes": contCounter = 0; continueInput = true; break;
case "no": contCounter = 0; continueInput = false; break;
default: contCounter = 1; continueInput = false; System.out.print("\nPlease only enter 'yes' or 'no'.");
}
} while (contCounter == 1);
} while (continueInput);
} // end main method
public static void add(Scanner stdin, ArrayList<Student> studentList) { // this is the one
String firstName;
String lastName;
String uid;
StudentType studentType;
ClassStanding studentClassStanding;
Major major;
double overallGPA;
double majorGPA;
String majorProfessor;
boolean thesisOption;
System.out.print("Please enter the student's first name: ");
String tempName = stdin.next();
firstName = checkName(tempName);
System.out.print("Please enter the student's last name: ");
tempName = stdin.next();
lastName = checkName(tempName);
System.out.println("Please enter the student's UID in the format 'U####' or 'U#####': ");
String tempUID = stdin.next();
uid = checkUID(tempUID).toUpperCase();
int count;
do {
System.out.print("Please enter the student's status as UNDECLARED, UNDERGRADUATE, or GRADUATE: ");
switch (stdin.next().toUpperCase()) {
case "UNDECLARED":
studentType = StudentType.UNDECLARED;
studentClassStanding = setStudentClassStanding(studentType);
count = 0;
Student student = new Student(firstName, lastName,
uid, studentType, studentClassStanding);
studentList.add(student);
break;
case "UNDERGRADUATE":
studentType = StudentType.UNDERGRADUATE;
major = setMajor();
studentClassStanding = setStudentClassStanding(studentType);
System.out.println("Enter the student's overall GPA below.");
overallGPA = setGPA();
System.out.println("Enter the student's major GPA below.");
majorGPA = setGPA();
count = 0;
UnderGraduate underGraduate = new UnderGraduate(firstName, lastName, uid, studentType,
studentClassStanding, major, overallGPA, majorGPA);
studentList.add(underGraduate);
break;
case "GRADUATE":
studentType = StudentType.GRADUATE;
studentClassStanding = setStudentClassStanding(studentType);
majorProfessor = setMajorProfessor();
thesisOption = setThesisOption();
count = 0;
Graduate graduate = new Graduate(firstName, lastName, uid, studentType,
studentClassStanding, majorProfessor, thesisOption);
studentList.add(graduate);
break;
default:
System.out.println("Please enter either Undeclared, Undergraduate, or Graduate only.");
count = 1;
}
} while (count == 1);
}
public static String checkName(String tempName) {
int a = 1;
String name1;
Scanner scanner = new Scanner(System.in);
do {
name1 = tempName; // hold the value of firstName in name1
for (int i = 0; i < tempName.length(); i++) { // loop to check input consists of letters (is a name)
if (!Character.isLetter(tempName.charAt(i))) { // if non-letters detected, ensure this was intentional
System.out.println("Please ensure you've entered the correct name. Re-enter the name or enter 'continue' to proceed: ");
tempName = scanner.nextLine();
if (tempName.equalsIgnoreCase("continue")) { // if user enters "continue", use original input
a = 0;
tempName = name1; // pass name1 value to firstName
break;
} else {
a = 1; // continue prompting for firstName
}
} else { // accept input
a = 0;
}
}
} while (a == 1); // loop to ensure proper input
return tempName;
} // end checkName method
public static String checkUID(String tempUID) {
Scanner scan = new Scanner(System.in);
int a;
do {
if (tempUID.charAt(0) == 'U' || tempUID.charAt(0) == 'u') {
if (tempUID.length() == 6 || tempUID.length() == 5) {
a = 0;
} else {
a = 1;
System.out.print("Please ensure input is in the form of U#### or U#####. Please re-enter the UID: ");
tempUID = scan.next();
}
} else {
a = 1;
System.out.print("Please ensure input is in the form of U#### or U#####. Please re-enter the UID: ");
tempUID = scan.next();
}
} while (a == 1);
return tempUID;
} // end checkUID method
public static ClassStanding setStudentClassStanding(StudentType studentType) {
Scanner scan = new Scanner(System.in);
int count;
ClassStanding studentTempClassStanding = null;
do {
if (studentType == StudentType.UNDECLARED || studentType == StudentType.UNDERGRADUATE) {
System.out.print("Please enter the student's class standing as either Freshman, Sophomore, Junior, Senior, or Unknown: ");
switch (scan.next().toUpperCase()) {
case "FRESHMAN":
studentTempClassStanding = ClassStanding.FRESHMAN;
count = 0;
break;
case "SOPHOMORE":
studentTempClassStanding = ClassStanding.SOPHOMORE;
count = 0;
break;
case "JUNIOR":
studentTempClassStanding = ClassStanding.JUNIOR;
count = 0;
break;
case "SENIOR":
studentTempClassStanding = ClassStanding.SENIOR;
count = 0;
break;
case "UNKNOWN":
studentTempClassStanding = ClassStanding.UNKNOWN;
count = 0;
break;
default:
System.out.println("Please enter only Freshman, Sophomore, Junior, Senior, or Unknown.");
count = 1;
}
} else {
System.out.print("Please enter the student's class standing as either 'Masters' for Masters Studies or 'PhD' for PhD Studies: ");
switch (scan.next().toUpperCase()) {
case "MASTERS": studentTempClassStanding = ClassStanding.MASTERS_STUDIES; count = 0; break;
case "PHD": studentTempClassStanding = ClassStanding.PHD_STUDIES; count = 0; break;
default: System.out.println("Please enter only 'Masters' or 'PhD'.");
count = 1;
}
}
} while (count == 1);
return studentTempClassStanding;
} // end setStudentClassStanding method
public static Major setMajor() {
Major tempMaj = null;
Scanner s = new Scanner(System.in);
int c;
do {
System.out.print("Please enter the student's major as either CS, CEG, EE, ISE, BME, ME, MET, or Unknown: ");
switch (s.next().toUpperCase()) {
case "CS":
tempMaj = Major.CS;
c = 0;
break;
case "CEG":
tempMaj = Major.CEG;
c = 0;
break;
case "EE":
tempMaj = Major.EE;
c = 0;
break;
case "ISE":
tempMaj = Major.ISE;
c = 0;
break;
case "BME":
tempMaj = Major.BME;
c = 0;
break;
case "ME":
tempMaj = Major.ME;
c = 0;
break;
case "MET":
tempMaj = Major.MET;
c = 0;
break;
case "UNKOWN":
tempMaj = Major.UNKNOWN;
c = 0;
break;
default:
System.out.println("Please enter only the specified values. ");
c = 1;
}
} while (c == 1);
return tempMaj;
} // end setMajor method
public static double setGPA() {
Scanner s = new Scanner(System.in);
double gpa;
int a;
do {
try {
System.out.print("Please enter the student's GPA: ");
gpa = s.nextDouble();// read in the gpa
if (gpa < 0.0 || gpa > 4.0) { // ensure the gpa is in the correct range
System.out.println("Invalid input, please enter a positive value between 0.0 and 4.0.");
a = 1;
} else {
a = 0;
}
} catch (InputMismatchException ex) { //catch any exceptions, prompt for correct input
a = 1;
gpa = 0.0;
System.out.println("Sorry, please enter a double value.");
s.nextLine(); // skip the last input
}
} while (a == 1 || gpa < 0.0 || gpa > 4.0); //loop while gpa is negative or incorrect input is received
return gpa;
} // end setGPA method
private static String setMajorProfessor() {
Scanner s = new Scanner(System.in);
String prof;
System.out.print("Please enter the name of the major professor: ");
String tempName = s.nextLine();
prof = checkName(tempName);
return prof;
} // end setMajorProfessor method
private static boolean setThesisOption() {
Scanner s = new Scanner(System.in);
boolean thesis = false;
int a;
do {
System.out.print("Please enter 'yes' if a thesis will be written, otherwise enter 'no': ");
switch (s.next().toUpperCase()) {
case "YES": thesis = true; a = 0; break;
case "NO": thesis = false; a = 0; break;
default: System.out.println("Please enter only 'yes' or 'no'."); a = 1;
}
} while (a == 1);
return thesis;
} // end setThesisOption method
}
The focus of this project is to have a menu of options for the user (add, list, save, sort, remove) that will allow them perform a series of operations on an arraylist they supply (through the add function). Obviously I'm not done and I'm not looking for help on my project, I'm just wondering if I made my "add" method too meaty. I tried to break it up as best I could by calling other methods to do a lot of the work in it, but I still feel like it might be too much work for the method. But then again it could be fine, I really don't know-I haven't yet gotten a feel for how much a method should really do.
Yes, this definitely does too much.
In software design, people have introduced what they call bad smells, GRASP patterns and design patterns to give more scientific arguments to a discussion.
Bad smells: also called antipatterns. They include for instance god class (a class that does everything), seems very applicable here. These are alarms that you should refactor your code.
GRASP patterns: these are more or less the directions in which your code should move. Two applicable here are controller and low coupeling: split I/O and data manipulation from each other and definitely make sure that most methods don't need data provided/stored by other methods/classes.
Design patterns: these are a set of patterns one can apply to achieve the GRASP patterns. For instance you can use a Factory to built new instances, or use a Chain of Responsiblity to split a problem into small subproblems that are handled separately.
Some final advices by quotes:
"Two or more, use a for" - E. W. Dijkstra
"A method should in most circumstances not contain more than 15 lines" - Some of my teachers
There are some rules and there are some tools to help with those rules. Basically using a static code analyzer helps to determine whether the method is too big or doing too many things. Findbugs is one of the famous static code analyzer.

is there any Exception in Java that to detect no input?

What Exception do I need to add to my try catch block if I want to detect if a user has entered any characters?
This is my code where I want to know if the user hasn't input anything or if the user's input was already saved in an addressbook. I am using an array to store my entries:
public void addEntry() {
entry[counter] = new AddressBookEntry();
entry[counter].setName(JOptionPane.showInputDialog("Enter name: "));
entry[counter].setAdd(JOptionPane.showInputDialog("Enter add: "));
entry[counter].setPhoneNo(JOptionPane.showInputDialog("Enter Phone No.: "));
entry[counter].setEmail(JOptionPane.showInputDialog("Enter E-mail: "));
counter++;
}
Do I need a try-catch or a condition? Here's my complete code:
public class AddressBook {
private AddressBookEntry entry[];
private int counter;
private String SName;
private int notfound = 0;
public static void main(String[] args) {
AddressBook a = new AddressBook();
a.entry = new AddressBookEntry[100];
int option = 0;
try {
while (option != 5) {
String content = "Choose an Option\n\n"
+ "[1] Add an Entry\n"
+ "[2] Delete an Entry\n"
+ "[3] Update an Entry\n"
+ "[4] View all Entries\n"
+ "[5] View Specific Entry\n"
+ "[6] Exit";
option = Integer.parseInt(JOptionPane.showInputDialog(content));
switch (option) {
case 1:
a.addEntry();
break;
case 2:
a.deleteEntry();
break;
case 3:
a.editEntry();
break;
case 4:
a.viewAll();
break;
case 5:
a.searchEntry();
break;
case 6:
System.exit(1);
break;
default:
JOptionPane.showMessageDialog(null, "Invalid Choice!");
}
}
}catch(NumberFormatException e){
JOptionPane.showMessageDialog(null, "Please Choose a Number in the displayed Menu");
}
}
public void addEntry() {
entry[counter] = new AddressBookEntry();
entry[counter].setName(JOptionPane.showInputDialog("Enter name: "));
entry[counter].setAdd(JOptionPane.showInputDialog("Enter add: "));
entry[counter].setPhoneNo(JOptionPane.showInputDialog("Enter Phone No.: "));
entry[counter].setEmail(JOptionPane.showInputDialog("Enter E-mail: "));
counter++;
}
public void viewAll() {
String addText = " NAME\tADDRESS\tPHONE NO.\tE-MAIL ADD\n\n";
int nonNull = 0;
for (int i = 0; i < entry.length; i++) {
if (entry[i] != null) {
addText = addText + entry[i].getInfo() + "\n";
nonNull++;
}
if (nonNull == counter) {
break;
}
}
JOptionPane.showMessageDialog(null, new JTextArea(addText));
}
public void searchEntry() {
SName = JOptionPane.showInputDialog("Enter Name to find: ");
searchMethod();
}
public void searchMethod() {
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
JOptionPane.showMessageDialog(null, entry[i].getInfo2());
notfound = 0;
break;
} else {
notfound++;
}
}
if (notfound != 0) {
JOptionPane.showMessageDialog(null, "Name Not Found!");
}
}
public void editEntry() {
SName = JOptionPane.showInputDialog("Enter Name to edit: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
entry[i] = new AddressBookEntry();
entry[i].setName(JOptionPane.showInputDialog("Enter new name: "));
entry[i].setAdd(JOptionPane.showInputDialog("Enter new add: "));
entry[i].setPhoneNo(JOptionPane.showInputDialog("Enter new Phone No.: "));
entry[i].setEmail(JOptionPane.showInputDialog("Enter new E-mail: "));
notfound = 0;
break;
} else {
notfound++;
}
}
if (notfound != 0) {
JOptionPane.showMessageDialog(null, "Name Not Found!");
}
}
public void deleteEntry() {
SName = JOptionPane.showInputDialog("Enter Name to delete: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
JOptionPane.showMessageDialog(null, "Found!");
entry[i] = null;
break;
}
}
}
}
I am having problem with my addEntry() method, because I want to detect if the user's new added entry was already stored in my addressbook and if the user doesn't typed anything when I ask "Enter Name:" in JOptionPane and still press OK.
Although not much clear about your question, I will try to answer it.
In this case, you can manually create your own exception here like,
throw new MyException();
Since your condition "The user didn't enter any character" is itself not clearer, I would suggest that you can try throwing exception by checking the no of arguments passed on the command-line.
If it's 0 i.e no arguments are passed, you can throw your own exception.
But by itself, no exception will be thrown.
I don't know of any exception, but you can use the length method.
Example:
input=(JOptionPane.showInputDialog(frame1, "what do you want?"));
if(input.length() > 0) {
l1.setText("a " + input + " on the way!");
}
else{
l1.setText("would you please choose something");
}
if length is greater then zero
From your updated question, it appears as if you are talking about user input from dialog boxes. The javadoc says that the showInputDialog methods return either the user's String (which could be empty) or null if the user canceled the dialog.
No exception is thrown. The user canceling the dialog is not "exceptional".
In general, when some method throws an exception and you don't catch it, either the compiler alerts you about this (for checked exceptions) or when the exceptions is thrown on runtime, you see a nice stack trace on the console (standard error). If you don't see this, then either you have caught (and thrown away) this exception, or there is no exception.
The user didn't enter any character by itself is not a condition which causes anyone to throw an exception, we would need more context.

Categories

Resources