0

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.

Maarten Bodewes
  • 80,169
  • 13
  • 121
  • 225
Rebellinho
  • 35
  • 5
  • 1
    `b` is `0`. Don't make everything a `static` field that you then shadow through variable names. Also, learn to use a debugger (or at least add print statements). – Elliott Frisch Feb 07 '20 at 00:19
  • 3
    You have a static field named `b`, but the `getAmount` method has a parameter named `b` which shadows it. So the line `b = scan.nextInt();` is assigning to that parameter, not to the static field, and hence the static field is still zero when you call `getInput`. – kaya3 Feb 07 '20 at 00:19
  • 1
    Judging from the fact that you made `b` a parameter to `getAmount` but this method only *assigns* to `b`, you appear to have the misconception that variables are passed by reference in Java. They are passed by value. – kaya3 Feb 07 '20 at 00:21

3 Answers3

1

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()?

Charles. Hi
  • 111
  • 1
  • 8
0

The code has several failures so I have rewritten it.

  1. As someone else pointed out, there is an issue with Scanner. Check the code.
  2. You are shadowing the static variable b because you were using it as a method parameter, and that is a bug and redundant.
  3. Also, you have a bug on how you were using the index at the 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

0

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));
        }
    }
}
Maarten Bodewes
  • 80,169
  • 13
  • 121
  • 225