简体   繁体   中英

Java bufferreader crashes on ctrl z

I'm making a game which plays until the user enters quit in the command line.

The user can enter different commands like get and go, with the get command the user can say what to get like, get baseball bat. What I do in my code is split the command.

everything is working fine but I have found a bug which I can't solve. If I enter "get" and press space and then ctrl + z it gets in a while loop which never ends.

It only happens with ctrl + z (1 time with ctrl c but after that 1 time not anymore)

 private void run() 
{       
    while (! quitCommand)
    {
        
        String input = null;
        
        try 
        {   
            input = null;
            System.out.println("Input "+ input);
            System.out.println("Give a command.");
            BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
            input = is.readLine();
            handleCommand(input);
            // As long as the command isn’t to quit:
            // get the next input line and handle it. (With handleCommand.)
        } 
        
        catch (Exception e) 
        {
            System.out.println("Something went wrong we are sorry try again.");
            e.printStackTrace();
        }
        
    }
}

/**
* @param userInput (This is the entire input string from the user.)
*
* (Tell others to) Perform the task which belongs to the given
* command.
*/
private void handleCommand(String userInput) 
{
    
    
    // Split the user input string.
    if (userInput != null)          // user input can not be empty
    {
        String[] delenTekst = userInput.split(" ");
        
        // The first word is a command. The rest is extra information
        String command = delenTekst[0];
        String extra = "";
        
        for (int i = 1; i < delenTekst.length; i ++)
        {
            if (i == 1)
            {
                extra = extra + delenTekst[i];
            }
            else
            {
                extra = extra +" " + delenTekst[i];
            }               
        }

        switch (command)
        {
            // Check if the command is to travel between rooms. If so, handle
            case "go"
            : 
                this.checkRoomTravel(extra);
                break;
            // If there isn't any room travel, then check all other command
            case "get"
            :   
                System.out.println("Looking for " +extra );
                this.handleGetCommand(extra);
                break;
            case "quit"
            :
                quitCommand = true;
                break;
            default
            :
                System.out.println("Command is not known try help for information");
                break;  
        }
    }
    else
    {
        userInput = "help";
    }
}

I'm new to java so it can be something really simple.

On the top of my script I have a private boolean quitCommand = false; which is to check if the user entered quit.

Ctrl + Z closes the Console and therefore your readLine() returns null as pretended to indicate that end of file was reached. So all you need to do, is to check for null returned by readLine() and handle this as you handle the "quit".

I've changed your code (just to test my thesis) and also stream lined a few things, eg you dont need to recreate a BufferedReader every time you read a line.

private boolean quitCommand = false;
 private void runIt() {       
     BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
     String input = null;

     while(!quitCommand) {
         try {   
             System.out.print("Give a command: ");
             input = is.readLine();

             // As long as the command isn’t to quit:
             if(input == null || "quit".equals(input.trim())) quitCommand = true;
             if(quitCommand) break;

             // get the next input line and handle it. (With handleCommand.)
             String[] words = input.trim().split("\\s+");

             // ** This is the original handleCommand line **
             System.out.println(input + ":" + Arrays.toString(words));
         } 
         catch (Exception e) {
             System.out.println("Something went wrong we are sorry try again.");
             e.printStackTrace();
         }
     }
 }

BTW: To split the input into words I'd use the regular expression as shown in my code. This works also if the user enters tabs or multiple spaces.

On DOS/Windows Ctrl + Z means end of input. This causes readLine() to return null no matter how many times you call it. This is likely to cause your code to fail as you don't appear to check for it. I suspect you are getting a NullPointerException which you are pretending didn't happen and trying again, endlessly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM