Reputation: 33
So i've recently started to write code in Java and i have rewritten one of my first programs trying to make it more elegant by using methods. Here is what i came up with:
import java.util.Scanner;
import java.util.ArrayList;
public class groceries {
static Scanner scan = new Scanner(System.in);
static ArrayList<String> shoppinglist = new ArrayList<>();
static int b = 0;
static String n ="";
public static void main(String[] args) {
getAmount(b);
getInput(b, n);
output();
}
private static void message (String m) {
System.out.println(m);
}
private static void getAmount(int b) {
message("How many articles do you want to buy?");
b = scan.nextInt();
}
private static void getInput(int b, String n) {
message("Which articles specifically do you want to buy?");
for (int i = 0; i <= b; i++) {
n = scan.nextLine();
shoppinglist.add(n);
}
}
private static void output() {
message("Here are your purchases:");
for (int k = 0; k<shoppinglist.size(); k++){
message(shoppinglist.get(k));
}
}
}
All works fine until I hit getInput
- I cannot enter any input. The program just wraps up and exits.
Upvotes: 0
Views: 78
Reputation: 94098
One mistake is to create too many fields. I've not refactored your class design, but I've removed all fields that are really not needed. I've left two: one for the input and one for the output, as they are not the essential input or output parameters of the functions. These would usually be instance variables rather than class variables (i.e. without static
).
Another mistake is a so called off-by-one. It is present if you have a zero based index i
and then you've got a number of items i <= b
. This is incorrect, it should be i < b
. However, because you forgot to remove the initial readline after the count b
was established, so you tried and fix it this way, probably leaving you with an item that's just the empty string ""
.
Here is some code where I also tried and rename your variables and names.
public class Groceries {
private static Scanner scan = new Scanner(System.in);
private static PrintStream out = System.out;
public static void main(String[] args) {
int b = retrieveAmountOfGroceries();
var shoppinglist = retrieveGroceries(b);
printPurchases(shoppinglist);
}
private static void message(String m) {
out.println(m);
}
private static int retrieveAmountOfGroceries() {
message("How many articles do you want to buy?");
int amount = scan.nextInt();
// remove the next newline
scan.nextLine();
return amount;
}
private static ArrayList<String> retrieveGroceries(int amountOfGroceries) {
var shoppinglist = new ArrayList<String>();
message("Which articles specifically do you want to buy?");
// note that we're having i < b not i <= b
for (int i = 0; i < amountOfGroceries; i++) {
String n = scan.nextLine();
shoppinglist.add(n);
}
return shoppinglist;
}
private static void printPurchases(ArrayList<String> shoppinglist) {
message("Here are your purchases:");
for (int i = 0; i < shoppinglist.size(); i++) {
message(shoppinglist.get(i));
}
}
}
Upvotes: 0
Reputation: 1097
The code has several failures so I have rewritten it.
Scanner
. Check the code.b
because you were using it as a method parameter, and that is a bug and redundant.for
loop of getInput
.Other minor fixes and here it is:
import java.util.Scanner;
import java.util.ArrayList;
public class Groceries {
static Scanner scan = new Scanner(System.in);
static ArrayList<String> shoppingList = new ArrayList<>();
static int b = 0;
public static void main(String[] args) {
getAmount();
getInput();
output();
}
private static void getAmount() {
System.out.println("How many articles do you want to buy?");
b = scan.nextInt();
System.out.println(b);
scan.nextLine(); // this is required
}
private static void getInput() {
System.out.println("Which articles specifically do you want to buy?");
for (int i = 0; i < b; i++) { // bug fixed
String n = scan.nextLine();
shoppingList.add(n);
}
}
private static void output (){
System.out.println("Here are your purchases:");
for (int i = 0; i< shoppingList.size(); i++){
System.out.println (shoppingList.get(i) );
}
}
}
Minor style fix: The method message
is redundant. Removed. Java coders are more familiar if they see System.out.println()
instead of message()
, and the first character of a class is suggested in uppercase (Groceries instead groceries). Object instances, on the other hand, start with lowercase character. You will need to rename your groceries.java file to Groceries.java
Upvotes: 0
Reputation: 119
You are calling a method nextInt()
before.
The problem is that nextInt() does not consume the '\n'
, so the next call to nextLine()
consumes it and then it's waiting to read the input for "Which articles specifically do you want to buy?".
You need to consume the '\n'
before calling nextLine()
.
private static void getAmount(int b) {
message("How many articles do you want to buy?");
b = scan.nextInt();
scan.nextLine();// adding this, it will force to consume the '\n'
}
Related to this: Scanner is skipping nextLine() after using next() or nextFoo()?
Upvotes: 1