Search code examples
javainputuser-inputsimulate

Simulating user input


I want to try and simulate multiple user inputs. I have this code

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class MainThing {

    public static void main(String[] args){
        //simulating user input
        String simulatedUserInput = "apple" + System.getProperty("line.separator") +
                                    "pie" + System.getProperty("line.separator");

        InputStream savedStandardInputStream = System.in;   //to reset
        System.setIn(new ByteArrayInputStream(simulatedUserInput.getBytes()));
        //----

        addMsg();

        //reset
        System.setIn(savedStandardInputStream);
    }

    //function to affect
    public static void addMsg()
    {
        String msg1 = inputOutput("Enter message 1");
        String msg2 = inputOutput("Enter message 2");
        System.out.println(msg1 +" " + msg2 );
    }

    //basically a scanner
    private static String inputOutput(String message) {
        System.out.println(message);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String returnString = "";
        try {
            returnString = br.readLine();
        }
        catch (IOException e){
            System.out.println("Error reading in value");
        }
        return returnString;
    }
}

I'm trying to simulate "apple pie ", but when I run it the 2nd message is always null. Is line.separator not suitable for this?


Solution

  • You shouldn´t intialize the BufferedReader twice. The first initialisation gets the whole input, whereas your second initialisation won´t have any further input to get, as the Stream did already consume all lines you previously "inserted". As though your second readline results in null

    The error can be resolved this way :

     // Create a static BR which you only initialize once
     static BufferedReader br;
    
    // Inside inputOutput
    ...
    private static String inputOutput(BufferedReader br, String message) {
        ....
        if (br == null)
            br = new BufferedReader(new InputStreamReader(System.in));
        ...
    }
    

    Or simply initialize the BufferedReader beforehand and pass it to the method.

    // function to affect
    public static void addMsg() {
        BufferedReader br =  new BufferedReader(new InputStreamReader(System.in));
        String msg1 = inputOutput(br, "Enter message 1");
        String msg2 = inputOutput(br, "Enter message 2");
        System.out.println(msg1 + " " + msg2);
    }
    // basically a scanner
    private static String inputOutput(BufferedReader br, String message) {
        System.out.println(message);
        String returnString = "";
        try {
            returnString = br.readLine();
        } catch (IOException e) {
            System.out.println("Error reading in value");
        }
        return returnString;
    }
    

    Edit: You could also provide the String input as array and create a ByteArrayInputStream for each array element, instead of a single ByteArrayInputStream from a single String.

    public static void main(String[] args){
        //simulating user input as array
        String simulatedUserInput[] = {"apple",
                                       "pie"};
    
        InputStream savedStandardInputStream = System.in;   //to reset
        //----
    
        addMsg(simulatedUserInput);
    
        //reset
        System.setIn(savedStandardInputStream);
    }
    
    //function to affect
    public static void addMsg(String[] simulatedUserInput)
    {
        String msg = "";
        // Loop over the input array and provide the input
        for (int i = 0;i < simulatedUserInput.length; ++i) {
            System.setIn(new ByteArrayInputStream(simulatedUserInput[i].getBytes()));
            msg += inputOutput("Enter message " + (i + 1)) + " ";
        }
        // output the input
        System.out.println(msg);
    }
    

    O/P in all cases:

    Enter message 1
    Enter message 2
    apple pie