简单的Java扫描程序问题

时间:2011-10-01 21:57:44

标签: java

我没有做过Java。在这个脚本中,它说Thread.sleep(10000);你仍然可以键入(我使用eclipse)我真的不知道为什么它让你在我没有uno.nextLine()时输入输出;在等待10秒之前或之后。请帮忙!感谢

import java.util.Scanner;
class Tutoiral{
        public static void main (String args[])throws InterruptedException {
            Scanner uno = new Scanner(System.in);
            Scanner uno1 = new Scanner(System.in);
            System.out.println("What's your name?");
            String name = uno.nextLine();
            System.out.println("Hi, " + name + ". Feel free to type whatever you want :) BUT DON'T SPAM!!!!!");

            String typed = (": ") + uno1.nextLine();
            System.out.println(name + typed + " (5 types remaining)");
            uno.nextLine();
            System.out.println(name + typed + " (4 types remaining)");
            uno.nextLine();
            System.out.println(name + typed + " (3 types remaining)");
            uno.nextLine();
            System.out.println(name + typed + " (2 types remaining)");
            uno.nextLine();
            System.out.println(name + typed + " (1 type remaining)");
            uno.nextLine();
            System.out.println(name + typed + " (If you type one more time, then I'll... I'll block you! Ha!)");
            uno.nextLine();
            System.out.println(name + typed + " (tut tut tut. You have been blocked for a while for spam. Don't type EVER again ok?)");
            Thread.sleep(10000);
            System.out.println("Ok, you can type again. But I wouldn't If I were you.");

3 个答案:

答案 0 :(得分:2)

  

我真的不知道为什么当我没有uno.nextLine()时,你可以输入输出;

nextLine的调用将从标准输入中读取(并返回)字符。控制台将打印用户输入的字符,无论您是否阅读

不幸的是(对你而言)阻止用户输入标准输入数据是不可能的。


一种解决方法可能是禁用“本地回声”,即避免打印用户输入的字符。我不知道该怎么做。一个讨厌的方法是做System.console().readPassword()

玩弄它,我提出了以下超级讨厌的黑客解决方法(请注意,例如,Thread.stop()已被弃用了。):

public static void turnOffLocalEcho(long ms) {
    Thread t = new Thread() {
        public void run() {
            while (true) { System.console().readPassword(); }
        }
    };

    t.start();

    try {
        Thread.sleep(ms);
    } catch (InterruptedException ie) {
    }

    t.stop();
}

只需调用此方法,即可将Thread.sleep(10000)的来电替换为

turnOffLocalEcho(10000);

答案 1 :(得分:0)

当调用其中一个nextSomething()方法时,

uno将处理输入的类型(在休眠,工作或等待输入时)。您无需调用nextSomething()并解析输入,但用户可以以任何方式输入。

答案 2 :(得分:0)

控制台输入(因此Scanner)不会像人们想象的那样工作。

控制台程序有一个名为standard input, or stdin的输入流。您可以将此视为要读取的程序的字符队列。

在控制台程序中键入字符时,它通常有2种效果:

  1. 终端会立即将字符打印到屏幕上。
  2. 该字符附加到程序的标准输入。 (从技术上讲,每次输入换行符时都会发生这种情况( Enter )。)
  3. 这些操作由操作系统执行,因此无论您的程序当前是否正在从标准输入读取数据,它们都能正常工作。如果程序正在等待数据,它将立即处理它(忽略输入流缓冲)。但如果没有(例如它正在处理其他内容,或者在你的情况下休眠10秒),那么该字符就会一直位于队列中,直到程序读取它为止。

    Scanner实际上并未提示用户输入一行文字。工作原理:当程序尝试从stdin读取时,如果没有可用数据,程序将阻塞,直到操作系统为其提供足够的数据Scanner.nextLine()从stdin读取字符,直到读取换行符为止,此时它返回自上一个换行符以来输入的字符。这意味着通常Scanner.nextLine()会导致程序等到用户按Enter键。

    但请注意,如果您一次输入多行文字,例如通过将几行粘贴到终端中,或通过shell管道或重定向(例如使用java MyProgram < file.txt),程序将一直运行,直到它吃完所有输入。

    当你的程序正在睡眠时,用户仍然可以输入并附加到程序的标准输入! (尝试在程序结束时添加一些System.out.println(name + typed + uno.nextLine());副本,并查看在程序休眠时键入时会发生什么。)

    因此,为防止用户输入主程序将读取的内容,您需要在主线程休眠时执行两项操作:

    1. 告诉控制台停止回显键入控制台的字符。
    2. 读取送到stdin的所有字符,然后丢弃它们。
    3. 您可以通过在另一个线程中调用System.console().readPassword()(并丢弃其输出)来执行这两个操作。这样,10秒后你的主线程将被唤醒并终止密码读取线程。但到那时,用户在主线程处于休眠状态时键入的任何内容都已经被读取(从stdin中删除)并被其他线程丢弃,因此实际上用户无法在控制台上键入内容。 (请参阅aioobe对此代码的回答。)