You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Java中含Scanner的while循环重启失效问题

Problem Analysis

The program terminates unexpectedly after the first execution loop due to unconsumed newline characters remaining in the Scanner buffer. This leads to an InputMismatchException in subsequent iterations when trying to read the typing speed integer.

Root Cause

  • scan.nextInt() reads the integer value for speed but leaves the trailing newline character in the buffer.
  • scan.next() reads the "y/n" choice but also leaves the trailing newline in the buffer.
  • In the next loop iteration, scan.nextLine() reads this leftover newline as an empty input string, and then scan.nextInt() attempts to parse an empty string as an integer, triggering an uncaught exception that terminates the program.
Fixed Code
import java.awt.AWTException;
import java.util.Scanner;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.Random;

public class PasteTyper {

    public static void main(String[] args) {
         Scanner scan = new Scanner(System.in);
         while (true) { 
            Random rand = new Random();
            System.out.print("\nEnter what to paste: ");
            String input = scan.nextLine();
            System.out.print("\nEnter typing speed (10 is recommended) (Lower is faster, higher is slower): ");
            int speed = scan.nextInt();
            scan.nextLine(); // Consume remaining newline after nextInt()
            
            try{Thread.sleep(3000);} catch(InterruptedException e){}
            
            for(int i = 0; i < input.length(); i++){
                try{Thread.sleep(rand.nextInt(30 * speed));} catch(InterruptedException e){}
                int delete = rand.nextInt(20 * speed);
                if(delete == 5){
                    int randomChar = rand.nextInt(10);
                    switch(randomChar){
                        case 1: convert('a'); break;
                        case 2: convert('b'); break;
                        case 3: convert('c'); break;
                        case 4: convert('d'); break;
                        case 5: convert('e'); break;
                        case 6: convert('f'); break;
                        case 7: convert('g'); break;
                        case 8: convert('h'); break;
                        case 9: convert('i'); break;
                        default:convert('j'); break;
                    }
                    try{Thread.sleep(40 * speed);} catch(InterruptedException e){}
                    doType(KeyEvent.VK_BACK_SPACE);
                    try{Thread.sleep(20 * speed);} catch(InterruptedException e){}
                }
                if(input.charAt(i) == '\\') {
                    if(i+1 < input.length() && input.charAt(i + 1) == 't') {
                        convert('\t');
                        i++;
                    }
                    else if(i+1 < input.length() && input.charAt(i + 1) == 'n') {
                        convert('\n');
                        i++;
                    }
                    else
                        convert(input.charAt(i));
                }   
                else
                    convert(input.charAt(i));
            }
            System.out.print("\nDo you want to paste again? (y/n): ");
            String choice = scan.next();
            scan.nextLine(); // Consume remaining newline after next()
            if(!choice.equalsIgnoreCase("y"))
                break;
         }
            
         scan.close();
    }
    
    public static void convert(char character){
            switch(character){
                case '\t' -> doType(KeyEvent.VK_TAB);
                case '\n' -> doType(KeyEvent.VK_ENTER);
                case 'a' -> doType(KeyEvent.VK_A);
                case 'b' -> doType(KeyEvent.VK_B);
                case 'c' -> doType(KeyEvent.VK_C);
                case 'd' -> doType(KeyEvent.VK_D);
                case 'e' -> doType(KeyEvent.VK_E);
                case 'f' -> doType(KeyEvent.VK_F);
                case 'g' -> doType(KeyEvent.VK_G);
                case 'h' -> doType(KeyEvent.VK_H);
                case 'i' -> doType(KeyEvent.VK_I);
                case 'j' -> doType(KeyEvent.VK_J);
                case 'k' -> doType(KeyEvent.VK_K);
                case 'l' -> doType(KeyEvent.VK_L);
                case 'm' -> doType(KeyEvent.VK_M);
                case 'n' -> doType(KeyEvent.VK_N);
                case 'o' -> doType(KeyEvent.VK_O);
                case 'p' -> doType(KeyEvent.VK_P);
                case 'q' -> doType(KeyEvent.VK_Q);
                case 'r' -> doType(KeyEvent.VK_R);
                case 's' -> doType(KeyEvent.VK_S);
                case 't' -> doType(KeyEvent.VK_T);
                case 'u' -> doType(KeyEvent.VK_U);
                case 'v' -> doType(KeyEvent.VK_V);
                case 'w' -> doType(KeyEvent.VK_W);
                case 'x' -> doType(KeyEvent.VK_X);
                case 'y' -> doType(KeyEvent.VK_Y);
                case 'z' -> doType(KeyEvent.VK_Z);
                case 'A' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_A);
                case 'B' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_B);
                case 'C' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_C);
                case 'D' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_D);
                case 'E' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_E);
                case 'F' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_F);
                case 'G' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_G);
                case 'H' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_H);
                case 'I' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_I);
                case 'J' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_J);
                case 'K' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_K);
                case 'L' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_L);
                case 'M' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_M);
                case 'N' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_N);
                case 'O' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_O);
                case 'P' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_P);
                case 'Q' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_Q);
                case 'R' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_R);
                case 'S' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_S);
                case 'T' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_T);
                case 'U' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_U);
                case 'V' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_V);
                case 'W' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_W);
                case 'X' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_X);
                case 'Y' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_Y);
                case 'Z' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_Z);
                case '`' -> doType(KeyEvent.VK_BACK_QUOTE);
                case '0' -> doType(KeyEvent.VK_0);
                case '1' -> doType(KeyEvent.VK_1);
                case '2' -> doType(KeyEvent.VK_2);
                case '3' -> doType(KeyEvent.VK_3);
                case '4' -> doType(KeyEvent.VK_4);
                case '5' -> doType(KeyEvent.VK_5);
                case '6' -> doType(KeyEvent.VK_6);
                case '7' -> doType(KeyEvent.VK_7);
                case '8' -> doType(KeyEvent.VK_8);
                case '9' -> doType(KeyEvent.VK_9);
                case '-' -> doType(KeyEvent.VK_MINUS);
                case '=' -> doType(KeyEvent.VK_EQUALS);
                case '~' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_QUOTE);
                case '!' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_1);
                case '@' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_2);
                case '#' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_3);
                case '$' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_4);
                case '%' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_5);
                case '^' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_6);
                case '&' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_7);
                case '*' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_8);
                case '(' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_9);
                case ')' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_0);
                case '_' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_MINUS);
                case '+' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_EQUALS);
                case '[' -> doType(KeyEvent.VK_OPEN_BRACKET);
                case ']' -> doType(KeyEvent.VK_CLOSE_BRACKET);
                case '\\' -> doType(KeyEvent.VK_BACK_SLASH);
                case '{' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_OPEN_BRACKET);
                case '}' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_CLOSE_BRACKET);
                case '|' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_SLASH);
                case ';' -> doType(KeyEvent.VK_SEMICOLON);
                case ':' -> doType(KeyEvent.VK_SHIFT,KeyEvent.VK_SEMICOLON);
                case '\'' -> doType(KeyEvent.VK_QUOTE);
                case '"' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_QUOTE);
                case ',' -> doType(KeyEvent.VK_COMMA);
                case '<' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_COMMA);
                case '.' -> doType(KeyEvent.VK_PERIOD);
                case '>' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_PERIOD);
                case '/' -> doType(KeyEvent.VK_SLASH);
                case '?' -> doType(KeyEvent.VK_SHIFT, KeyEvent.VK_SLASH);
                case ' ' -> doType(KeyEvent.VK_SPACE);
                default -> throw new IllegalArgumentException("Cannot type character " + character);
               
            }
        } 
        
        public static void doType(int keycode){
            try{
                Robot robot = new Robot();
                robot.keyPress(keycode);
                robot.keyRelease(keycode);
            }
            catch(AWTException e){
                e.printStackTrace();
            }
        }
        public static void doType(int keycode1, int keycode2){
            try{
                Robot robot = new Robot();
                robot.keyPress(keycode1);
                robot.keyPress(keycode2);
                robot.keyRelease(keycode2);
                robot.keyRelease(keycode1);
            }
            catch(AWTException e){
                e.printStackTrace();
            }
        }
}

Key Changes Made

  1. Buffer cleanup: Added scan.nextLine() after scan.nextInt() and scan.next() to clear trailing newline characters from the input buffer, preventing empty inputs in subsequent loops.
  2. Bounds safety: Added i+1 < input.length() checks before accessing input.charAt(i+1) to avoid IndexOutOfBoundsException when input ends with a backslash.
  3. Flexible input handling: Changed choice check to equalsIgnoreCase("y") to accept both 'y' and 'Y' as valid continuation inputs.
  4. Correct key sequence: Fixed key release order in the two-parameter doType method to release non-modifier keys first, ensuring proper keyboard emulation.
  5. Debug visibility: Added e.printStackTrace() to AWT exception handlers to help diagnose Robot class issues.

内容的提问来源于stack exchange,提问作者Luka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:34:52