Java: วิธีรับอินพุตจาก System.console ()


162

ฉันพยายามที่จะใช้คลาสคอนโซลที่จะได้รับข้อมูลจากผู้ใช้ แต่วัตถุ null System.console()ถูกส่งกลับเมื่อผมเรียก ฉันต้องเปลี่ยนอะไรก่อนที่จะใช้ System.console?

Console co=System.console();
System.out.println(co);
try{
    String s=co.readLine();
}

1
สำหรับ Android หรือไม่ (ฉันคาดเดาจากรหัสผู้ใช้ของคุณ)
Ryan Fernandes

คุณใช้ eclipse เพื่อเริ่มโปรแกรมของคุณหรือไม่ ลองเริ่มโปรแกรมของคุณโดยไม่ใช้ eclipse โดยใช้ java.exe
keuleJ

5
มีลักษณะที่โครงการของ McDowell "AbstractingTheJavaConsole" A: illegalargumentexception.googlecode.com/svn/trunk/code/java/...
athspk

7
@RyanFernandes ชื่อของเขาเกี่ยวข้องกับคำถามของเขาอย่างไร
b1nary.atr0phy

คำตอบ:


238

การใช้ Console เพื่ออ่านอินพุต (ใช้งานได้เฉพาะด้านนอกของ IDE):

System.out.print("Enter something:");
String input = System.console().readLine();

อีกวิธีหนึ่ง (ทำงานได้ทุกที่):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) throws IOException { 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Enter String");
        String s = br.readLine();
        System.out.print("Enter Integer:");
        try {
            int i = Integer.parseInt(br.readLine());
        } catch(NumberFormatException nfe) {
            System.err.println("Invalid Format!");
        }
    }
}

System.console () ส่งคืน null ใน IDE
ดังนั้นหากคุณต้องการจริงๆที่จะใช้System.console()อ่านนี้การแก้ปัญหาจาก McDowell


เหตุใดเราจึงต้องการ BufferedReader เพื่ออ่านอินพุตทำไมเราไม่สามารถอ่านได้โดยตรงจาก InputStreamReader
ผู้เรียน

2
ได้คำตอบ: ด้วย BufferedInputStream วิธีการจะมอบหมายให้กับวิธีการอ่านที่โอเวอร์โหลด () ที่อ่านจำนวนไบต์ 8192 และบัฟเฟอร์จนกว่าพวกเขาจะมีความจำเป็น มันยังคงส่งกลับเฉพาะไบต์เดียว (แต่เก็บไว้อื่น ๆ สำรอง) วิธีนี้ทำให้ BufferedInputStream ทำให้การโทรแบบเนทีฟไปยังระบบปฏิบัติการอ่านจากไฟล์น้อยลง ขอบคุณ
ผู้เรียน

ในกรณีที่เราต้องการอ่านรหัสผ่านจากผู้ใช้stackoverflow.com/questions/22545603/…จะปิดบังบรรทัดด้วยเครื่องหมายดอกจัน
oraclesoon

@Learner อีกเหตุผลหนึ่งที่อาจเป็นไปได้ว่า BufferedReader ให้วิธีการซึ่งไม่ได้มีอยู่สำหรับreadLine() InputStreamReader
Marcono1234

116
Scanner in = new Scanner(System.in);

int i = in.nextInt();
String s = in.next();

4
อย่างไรก็ตามnextLine()ยุ่งมากที่จะทำงานกับ ที่ดีที่สุดมันจะทำให้คุณปวดหัวเมื่อพยายามรับทั้งบรรทัดจากคอนโซล
Yokhen

9
@Yokhen คุณช่วยยกตัวอย่างที่in.nextLine()สร้างปัญหาได้มั้ย
ajay

2
(1) โดยค่าเริ่มต้นตัวคั่นของสแกนเนอร์เป็นพื้นที่ดังนั้นเมื่อผู้ใช้ป้อนข้อความหลายข้อความมันจะทำให้ซอฟต์แวร์ดำเนินการต่อไปอีกไม่กี่ถัดไป () และตรรกะในซอฟต์แวร์ของเราจะผิด (2) ถ้าฉันใช้ nextLine () เพื่ออ่านประโยคทั้งหมดซึ่งรวมถึงช่องว่างและ \ n \ r ฉันต้องตัด () อินพุตของผู้ใช้ (3) ถัดไป () จะรอการป้อนข้อมูลของผู้ใช้ แต่ nextLine () จะไม่ (4) ฉันทดสอบ useDelimiter ("\\ r \\ n") แต่มันทำให้ตรรกะถัดไป () ในซอฟต์แวร์ของเราที่อื่นผิดไปอีกครั้ง สรุปแล้วมันค่อนข้างยุ่งที่จะใช้ Scanner เพื่ออ่านอินพุตของผู้ใช้ BufferedReader ดีที่สุด
oraclesoon

ฉันมีปัญหากับสแกนเนอร์โดยเฉพาะฉันได้รับสิ่งjava.util.NoSuchElementExceptionที่ฉันไม่ค่อยเข้าใจ
Romain Vincent

ทั้งหมดนี้ควรอยู่ในการลองกับทรัพยากรและวิธีการควรเป็น in.nextLine () หากคุณต้องการอ่านบรรทัด
Calabacin

35

มีวิธีอ่านสตริงอินพุตจากคอนโซล / คีย์บอร์ดของคุณ โค้ดตัวอย่างต่อไปนี้แสดงวิธีอ่านสตริงจากคอนโซล / คีย์บอร์ดโดยใช้ Java

public class ConsoleReadingDemo {

public static void main(String[] args) {

    // ====
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    System.out.print("Please enter user name : ");
    String username = null;
    try {
        username = reader.readLine();
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println("You entered : " + username);

    // ===== In Java 5, Java.util,Scanner is used for this purpose.
    Scanner in = new Scanner(System.in);
    System.out.print("Please enter user name : ");
    username = in.nextLine();      
    System.out.println("You entered : " + username);


    // ====== Java 6
    Console console = System.console();
    username = console.readLine("Please enter user name : ");   
    System.out.println("You entered : " + username);

}
}

ส่วนสุดท้ายของรหัสที่ใช้java.io.Consoleเรียน คุณไม่สามารถรับอินสแตนซ์ของคอนโซลได้System.console()เมื่อรันโค้ดตัวอย่างผ่าน Eclipse เนื่องจาก eclipse รันแอ็พพลิเคชันของคุณเป็นกระบวนการส่วนหลังและไม่เป็นกระบวนการระดับบนสุดที่มีคอนโซลระบบ


18

มันจะขึ้นอยู่กับสภาพแวดล้อมของคุณ หากคุณใช้ Swing UI ผ่านjavawตัวอย่างเช่นไม่มีคอนโซลที่จะแสดง หากคุณกำลังทำงานภายใน IDE มันจะขึ้นอยู่กับการจัดการคอนโซลของ IDE เฉพาะของ IDE

จากบรรทัดคำสั่งมันควรจะดีแม้ว่า ตัวอย่าง:

import java.io.Console;

public class Test {

    public static void main(String[] args) throws Exception {
        Console console = System.console();
        if (console == null) {
            System.out.println("Unable to fetch console");
            return;
        }
        String line = console.readLine();
        console.printf("I saw this line: %s", line);
    }
}

รันสิ่งนี้ด้วยjava:

> javac Test.java
> java Test
Foo  <---- entered by the user
I saw this line: Foo    <---- program output

ตัวเลือกอื่นคือการใช้System.inซึ่งคุณอาจต้องการตัดในBufferedReaderบรรทัดเพื่ออ่านหรือใช้Scanner(การตัดอีกครั้งSystem.in)


7

พบคำตอบที่ดีเกี่ยวกับการอ่านจากคอนโซลที่นี่อีกวิธีใช้ 'สแกนเนอร์' เพื่ออ่านจากคอนโซล:

import java.util.Scanner;
String data;

Scanner scanInput = new Scanner(System.in);
data= scanInput.nextLine();

scanInput.close();            
System.out.println(data);

1
คุณอาจไม่ต้องการเรียกclose()ใช้เครื่องสแกนในกรณีนี้เพราะมันจะปิด System.in และป้องกันไม่ให้แอปพลิเคชันของคุณอ่านในภายหลัง (การอ่านในภายหลังจะพ่นข้อผิดพลาด "ไม่พบบรรทัด")
เทรเวอร์

ใช่ฉันยอมรับว่าไม่ควรใช้ปิด () หากตั้งใจจะใช้ System.in ในภายหลังในโปรแกรม
akhouri

5

ลองสิ่งนี้ หวังว่าจะช่วยได้

    String cls0;
    String cls1;

    Scanner in = new Scanner(System.in);  
    System.out.println("Enter a string");  
    cls0 = in.nextLine();  

    System.out.println("Enter a string");  
    cls1 = in.nextLine(); 

3

ต่อไปนี้ใช้คำตอบของ athspkและทำให้เป็นคำตอบที่วนซ้ำอย่างต่อเนื่องจนกว่าผู้ใช้จะพิมพ์ "exit" ฉันยังได้เขียนคำตอบติดตามที่ฉันใช้รหัสนี้และทำให้มันทดสอบได้

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class LoopingConsoleInputExample {

   public static final String EXIT_COMMAND = "exit";

   public static void main(final String[] args) throws IOException {
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("Enter some text, or '" + EXIT_COMMAND + "' to quit");

      while (true) {

         System.out.print("> ");
         String input = br.readLine();
         System.out.println(input);

         if (input.length() == EXIT_COMMAND.length() && input.toLowerCase().equals(EXIT_COMMAND)) {
            System.out.println("Exiting.");
            return;
         }

         System.out.println("...response goes here...");
      }
   }
}

ตัวอย่างผลลัพธ์:

Enter some text, or 'exit' to quit
> one
one
...response goes here...
> two
two
...response goes here...
> three
three
...response goes here...
> exit
exit
Exiting.

3

ฉันเขียนไลบรารีText-IOซึ่งสามารถจัดการกับปัญหาของ System.console () เป็นโมฆะเมื่อเรียกใช้แอปพลิเคชันจากภายใน IDE

แนะนำชั้น abstraction คล้ายกับที่เสนอโดยMcDowell ถ้า System.console () ส่งคืน null ไลบรารีจะสลับไปยังคอนโซลแบบสวิง

นอกจากนี้ Text-IO ยังมีคุณสมบัติที่มีประโยชน์หลายแบบ:

  • รองรับการอ่านค่าด้วยชนิดข้อมูลต่าง ๆ
  • อนุญาตให้ปิดบังอินพุตเมื่ออ่านข้อมูลที่ละเอียดอ่อน
  • อนุญาตให้เลือกค่าจากรายการ
  • อนุญาตให้ระบุข้อ จำกัด เกี่ยวกับค่าอินพุต (รูปแบบการจัดรูปแบบช่วงค่าข้อ จำกัด ด้านความยาว ฯลฯ )

ตัวอย่างการใช้งาน:

TextIO textIO = TextIoFactory.getTextIO();

String user = textIO.newStringInputReader()
        .withDefaultValue("admin")
        .read("Username");

String password = textIO.newStringInputReader()
        .withMinLength(6)
        .withInputMasking(true)
        .read("Password");

int age = textIO.newIntInputReader()
        .withMinVal(13)
        .read("Age");

Month month = textIO.newEnumInputReader(Month.class)
        .read("What month were you born in?");

textIO.getTextTerminal().println("User " + user + " is " + age + " years old, " +
        "was born in " + month + " and has the password " + password + ".");

ในภาพนี้คุณสามารถเห็นโค้ดด้านบนที่ทำงานอยู่ในคอนโซลแบบสวิง


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.