【问题标题】:Whats wrong with InputStreamReader here?InputStreamReader 有什么问题吗?
【发布时间】:2017-09-08 08:53:05
【问题描述】:

我创建了一个 Java 购物车应用程序。我已经为此使用了 InputStreamReader 类。但它表现出奇怪的行为。我已经尝试过 Scanner 类和 Data Input Stream 类。但他们似乎不适合这个应用程序。

谁能指出这门课有什么问题?

同样如前所述,Scanner 类和 DIS 类倾向于跳过用户输入,与使用 ISR 类时相同(请参阅输出:速率)。我厌倦了尝试每个 Java 用户输入实用程序类,并一次又一次地修改我的代码。

import java.util.ArrayList;
//import java.util.InputMismatchException;
import java.util.Iterator;
import java.util.Scanner;
import java.io.DataInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.lang.Throwable;


public class NewShop {


protected ArrayList<NewItem> ItemList;
ArrayList<NewItem> cartList ;

   // public DataInputStream dis = new DataInputStream(System.in);
   // private Scanner sc = new Scanner(System.in);
  private InputStreamReader isr = new InputStreamReader(System.in);

 public void addItem() {

    long aCode = 0;
    String aName ="";
    double aRate = 0;
    int aQuantity = 0;
    NewItem foundItem;

    System.out.println("Enter Item code:");
   /* try{
    String adddisString = dis.readLine();}
      catch(IOException e){e.printStackTrace();} */

    try{
    aCode = isr.read();
      System.out.println("code entered is : " + aCode);
       }
         catch(IOException e){e.printStackTrace();}

    foundItem = search(aCode);
    if (foundItem == null) {
        System.out.println("Item name : ");
        try{
        aName = dis.readLine();
          }
             catch(IOException e){e.printStackTrace();}
        System.out.println("Rate : "); 
        try{ aRate = isr.read(); }
           catch(IOException e){e.printStackTrace();}

        System.out.println("Quantity : ");
        try{aQuantity = isr.read();}
        catch(IOException e){e.printStackTrace();}


                  NewItem aItem = new NewItem(aName, aRate, aCode, aQuantity);
                  ItemList.add(aItem);
                  }
                  else {
                  System.out.println("Item exists");
                  }


  } 

}

输出:

shachindratripathi@saurabh-OptiPlex-3010:~/NewJava$ java NewShoppingCart
  New Shop for Items created.
  -----ITEM------
1. Display all items
2. Search items
3. Add items to list
4. Add items to cart
5. Issue item
6. Exit
Choice:
3
Enter Item code:
1
code entered is : 49
Item name : 
apple
Rate : 
Quantity : 
30
1. Display all items
2. Search items
3. Add items to list
4. Add items to cart
5. Issue item
6. Exit
Choice:
1
       code           name           rate          quantity 

        49            apple           10.0           51

                              ************ 
1. Display all items
2. Search items
3. Add items to list
4. Add items to cart
5. Issue item
6. Exit
Choice:

【问题讨论】:

  • 你的预期输出是什么?
  • 您能否尝试进一步缩进您的代码并提供minimal reproducible example? (有一些数据)
  • 参见“输出”部分。我认为预期的输出肯定是显而易见的。
  • 好吧,我看到Enter Item code:1 code entered is : 49 不是你想要的......但你看到它在哪里了吗?您正在使用read() 读取每个字节的流字节,您将获得char 值,1 = 49 看到ASCII table
  • 你想达到什么目的? isr.read() 以整数形式返回 inupt 的下一个字符,您将其放入 long 变量中。第一个输入的字符是1,所以变量得到了它的代码49...

标签: java java.util.scanner datainputstream inputstreamreader


【解决方案1】:

InputStreamReader 允许您使用read 读取每个字符的流字符,从而为您提供int

那个int不是你想的值,它是一个数字的char表示,所以

'0' = 48
'1' = 49
...

更多内容在ASCII table

您可能想在这里使用Scanner,这在您的情况下更简单,或者BufferedReader,让您有可能在String 中获得完整的行。

Scanner sc = new Scanner(System.in);
int i = sc.nextInt(); //This will get the next number an parse it in an integer (or throw an exception)
//careful, the <ENTER> is still in the buffer, flush with sc.nextLine(); if needed
sc.close();

您使用Scanner 跳过了一些输入的原因在上面,当您读取特定类型(如readInt)时,未读取“输入”键,因此它保留在缓冲区中,下一次调用nextLine 将阅读它。您需要先清除该输入,然后才能获得正确的值。

int i = sc.nextInt(); 
sc.nextLine(); //clear <enter>
String s = sc.nextLine(); //next input

【讨论】:

  • @UsagiMiyamoto 确实,一个字符可能不止一个字节,所以说得不好!谢谢。已更正
  • 非常需要帮助。谢谢!但是,即使它没有要求用户输入,您能否说明它是从哪里将值“10.0”分配给“Rate”的?
  • @SHACHINDRATRIPATHI 好吧,您使用了已弃用的DateInputStream.readLine(),而且我认为此类不适合文本输入。但是方法指向BufferedReader,只需听文档;)基本上,enter 相当于0x13 0x10 字符,它使用0x13 找到“新行”,留下0x10 在缓冲区,值在下一个read()(用于速率的那个)上使用。解释你得到的价值
【解决方案2】:

如果您使用Readers,您必须自己转换任何非字符串值。 DataInputs 使用二进制格式,不适合用户输入。

因此,您最简单的解决方案是 Scanner,因此请尝试以下操作:

public class NewShop
{
  protected ArrayList<NewItem> ItemList;
  ArrayList<NewItem> cartList ;
  private Scanner in = new Scanner(System.in);
  public void addItem()
  {
    long aCode = 0;
    String aName ="";
    double aRate = 0;
    int aQuantity = 0;
    NewItem foundItem;
    System.out.println("Enter Item code:");
    try
    {
      aCode = in.nextLong(); // this reads the to the first char that is not part of the 
      in.nextLine();         // long value, so we need to read till the end of the line...
      System.out.println("code entered is : " + aCode);
      foundItem = search(aCode);
      if (foundItem == null)
      {
        System.out.println("Item name : ");
        aName = in.nextLine();
        System.out.println("Rate : "); 
        aRate = in.nextDouble();
        in.nextLine();
        System.out.println("Quantity : ");
        aQuantity = in.nextInt();
        in.nextLine();
        NewItem aItem = new NewItem(aName, aRate, aCode, aQuantity);
        ItemList.add(aItem);
      }
      else
      {
        System.out.println("Item exists");
      }
    }
    catch(IOException e)
    {
      e.printStackTrace();
    }
  } 
}

还去掉了内部的try-catches 好像有什么值错了,以后就不行了……

【讨论】:

  • 哦,第一个不是有评论吗?
  • 在评论中 ;) 我没有阅读完整的代码,所以看不到它(尤其是大代码),但我想这对新手来说已经足够了。
【解决方案3】:

你这样做:

aCode = isr.read();

返回您输入的第一个字符的 Int 值(请参阅Ascii-Table)。 因此,对于您输入的“1”,您将获得“1”的 Ascii 代码,即 49。

如果你想用 InputStreamReader 读取字符串,可以这样做:

InputStreamReader isr = new InputStreamReader(System.in)
int c;
String input = "";
while((c = isr.read()) != -1){
        input+= (char) c;
}

但是,如果您使用扫描仪来处理这类事情,您会得到更好、更容易的结果,请参阅@AxelH 对此的回答。

【讨论】:

  • 关于input : 30 ?
  • 你会得到返回为 Int 的第一个字符,即 "3" 的 "51"
  • 这是个问题... ;)
  • 谢谢。关于在此处为 ISR 类使用哪种方法以便获得预期输出的任何建议?
  • @SHACHINDRATRIPATHI 我强烈建议您使用 Scanner 或 BufferedReader ...但如果您坚持使用 ISR 读取字符串。你需要这样的东西:查看更新的答案。
猜你喜欢
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 2021-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
相关资源
最近更新 更多