解析输入而不使用除System.in.read()之外的任何内容

时间:2012-10-28 15:08:27

标签: java input io

我很难找到有关System.in.read();如何运作的细节,也许有人可以帮助我。看起来像扫描仪会更好,但我不允许使用它。

我得到了一个任务,我应该以Boolean-Operator-Boolean的形式读取控制台用户输入,例如T ^ F或T& T通过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()之后等待用户输入并使其正确检查char输入。然而,在此之后,所有后续System.in.read()都将被忽略,程序将终止。

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

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

3 个答案:

答案 0 :(得分:3)

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

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");
    }
}

答案 1 :(得分: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的源代码。

答案 2 :(得分: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数组的第一个char。其余的代码以相同的方式进行修改,您甚至可以使用相同的缓冲区数组(input)并查询第0个元素。