4

我很难找到有关确切System.in.read();工作原理的详细信息,也许有人可以帮助我。似乎 Scanner 会更好,但我不允许使用它。

我被分配了一个任务,我应该以 Boolean-Operator-Boolean 形式读取控制台用户输入,例如 T^F 或 T&T via System.in.read(),然后简单地打印语句返回的内容。

普通人可能会使用不同的方法,但作业明确指出只有System.in.read()System.out.println()被允许。

这是我解决它的尝试:

import java.io.*;

public static void main(String[] args) {

  String error = "Reading error, please use T or F";

  boolean a = true;  //char: 84 or 116 for T and t
  boolean b = false; //char: 70 or 102 for F and f
  int userChar1;
  int userOperator;
  int userChar2;
  int chosenOperator = 0;

  try {

    //Get first char
    System.out.println("Enter the first value (T or F):");
    userChar1 = System.in.read();

    if((userChar1==84)||(userChar1==116)) { // T or t
      a = true;
    } else if ((userChar1==70)||(userChar1==102)) { // F or f
      a = false;
    } else {
      System.out.println(error);
    }


    //Get second char
    System.out.println("Select an operator:  &  |  ^");
    userOperator = System.in.read();

    if(userOperator==38) { // &
      chosenOperator = 0;
    } else if (userOperator==124) { // |
      chosenOperator = 1;
    } else if (userOperator==94) { // ^
      chosenOperator = 2;
    } else {
      System.out.println(error);
    }


    //Get third char 
    System.out.println("Enter the second value:");
    userChar2 = System.in.read();
    System.in.close();
    if((userChar2==84)||(userChar2==116)) {
      b = true;
    } else if ((userChar2==70)||(userChar2==102)) {
      b = false;
    } else {
      System.out.println(error);
    }


    //Figure out result
    boolean result;
    switch (chosenOperator) {
    case 0:
      result = a&b;   
    case 1:
      result = a|b;
    case 2:
      result = a^b;

      System.out.println(result);

    }

  } catch(IOException e) {

  }
}

执行此代码使控制台在第一个之后等待用户输入,System.in.read()并让它正确检查字符输入。然而,在那之后,所有成功System.in.read()的都被忽略并且程序终止。

我找到了一段使用的代码System.in.close(),所以仍然不知道我在每次之后拼接的方法到底是什么System.in.read()。这导致程序System.in.read()在 a 之后的第一个System.in.close()被调用时终止。

那么,到底发生了什么?你会如何System.in.read()正确使用?

4

3 回答 3

4

问题不在于 System.in.read(),而在于控制台。控制台通常是缓冲的,这意味着只有在按下回车键后数据才会发送到您的程序(因此可以由 System.in.read() 读取)。因此,您必须将控制台切换到无缓冲模式,但没有可移植的方式来执行此操作,因为有很多不同类型的控制台(unix shell、cmd 窗口、Eclipse 控制台等)。
如果不允许使用 System.in.read() 和 System.out.println() 方法以外的任何方法,则必须让用户在一行中输入完整的术语,然后按 enter 即可处理字符输入,例如:

public static void main(String[] args) throws IOException {
    boolean a = true; // char: 84 or 116 for T and t
    boolean b = false; // char: 70 or 102 for F and f
    int userChar1;
    int userOperator;
    int userChar2;

    System.out.println("Please enter the term, e.g. T&F:");

    userChar1 = System.in.read();
    userOperator = System.in.read();
    userChar2 = System.in.read();

    a = userChar1 == 'T' || userChar1 == 't';
    b = userChar2 == 'T' || userChar1 == 't';

    switch (userOperator) {
    case '&':
        System.out.println(a & b);break;
    case '|':
        System.out.println(a | b);break;
    case '^':
        System.out.println(a ^ b);break;
    default:
        System.out.println("unknow operator");
    }
}
于 2012-10-28T16:05:33.737 回答
1

查看以下代码部分:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String input = null;

//  read the input from the command-line; need to use try/catch with the
//  readLine() method
try {
input = br.readLine();
} catch (IOException e) {
      System.out.println("IO error trying to read your input!");
      System.exit(1);
}
System.out.println("your input: "+input);

如果您不允许使用 bufferReader,我建议您查看 bufferReader 的源代码。

于 2012-10-28T15:19:34.283 回答
1

就我个人而言,运行你的代码没有问题,但它有一些我必须研究的奇怪效果。

这种方法(使用System.in.read())的主要问题是,当用户输入某个字符时,他必须按下enter,因此您有 2 个字符而不是您期望的 1 个字符 - 用户输入的第一个字符(假设 T 或 F 在您的大小写)和换行符。

我设法让您的代码进行了微小的更改。您需要调用read()方法的重载版本 -read(byte[] b)内容为some number of bytes from the input stream and stores them into the buffer array.

这是您的代码的第一部分,已修改:

byte[] input = new byte[10];
System.out.println("Enter the first value (T or F):");
System.in.read(input);
userChar1 = input[0];
if ((userChar1 == 84) || (userChar1 == 116)) { // T or t
    a = true;
} else if ((userChar1 == 70) || (userChar1 == 102)) { // F or f
    a = false;
} else {
    System.out.println(error);
}

注意,我们不关心返回什么,我们只关心数组read()中的第一个字符。input其余代码以相同方式修改,您甚至可以使用相同的缓冲区数组 ( input) 并查询第 0 个元素。

于 2012-10-28T15:50:31.040 回答