2015-11-11 13 views
8

मैं जावा सीख रहा हूं और निम्नलिखित डीओ टाइप कर रहा हूं ... उदाहरण उदाहरण। यदि मैं 'q' टाइप करता हूं तो प्रोग्राम छोड़ दिया जाएगा। यह चलता है लेकिन मुझे "पंक्ति के बाद एक कुंजी कृपया" की तीन पंक्तियां क्यों मिलती हैं: "?एक बहुत ही सरल जावा ... जबकि लूप

class DWDemo { 
    public static void main (String args[]) 
     throws java.io.IOException { 
      char ch; 
      do { 
       System.out.println("Please a key followed by ENTER:"); 
       ch = (char) System.in.read(); 
      } while (ch != 'q'); 
     } 
} 

enter image description here

उत्तर

10

क्योंकि जब आप टाइप a और Enter मारा, तो in.read() विधि तीन पात्रों देता है। (ध्यान दें कि संयोजन \r\n को विंडोज के तहत लाइन-ब्रेक माना जाता है)।

यदि आप इसे लिनक्स या ओएसएक्स के तहत चलाते हैं तो आपके प्रोग्राम में काफी अलग व्यवहार होगा, क्योंकि लाइन-ब्रेकिंग कैरेक्टर ओएस के लिए विशिष्ट है जिस पर आप प्रोग्राम चला रहे हैं। लिनक्स के तहत, यह \n होगा, ओएस एक्स-9 के तहत यह \r होगा, उदाहरण के लिए।

एक के रूप में काम के आसपास, आप पूरी लाइन (एक Scanner का उपयोग करके) पढ़ सकते हैं और यह ट्रिम, जो लाइन तोड़ने चरित्र (ओएस प्रकार disregarding) छोड़ देगा:

public static void main (String args[]) throws java.io.IOException { 
     String line; 
     Scanner sc = new Scanner(System.in); 
     do { 
      System.out.println("Please a key followed by ENTER:"); 
      line = sc.readLine().trim(); 
     } while (!"q".equals(line)); 
    } 
5

मुझे लगता है क्या के रूप में इनपुट अपने ENTER कुंजी दबाने से युक्त है पढ़ा जाता है। चूंकि आप विंडोज़ पर हैं, इसमें सीआरएफएल लाइन समाप्त हो रही है।

इस प्रकार, प्रत्येक बार जब आप अपने चार में प्रवेश करते हैं, तो आप वास्तव में 3 वर्ण इनपुट करते हैं। अपना पहला इनपुट के लिए:

  1. एक
  2. सीआर
  3. वामो

एक BufferedReader के माध्यम से पूरी लाइन को पढ़ने की कोशिश करो और एक खाली स्थान के उस पर ट्रिम चलाने के लिए, या सिर्फ अपनी पहली चार मूल्यांकन करते हैं। 'a', गाड़ी वापसी \r के लिए चरित्र और लाइन ब्रेक के लिए चरित्र ('\n') -

3

जब टाइपिंग विंडोज सिस्टम पर कमांड लाइन पर इनपुट, सभी लाइनें लाइन फीड में समाप्त होती हैं जिसमें वर्ण \r\n शामिल हैं। तो जब आप पहली बार a टाइप करते हैं, तो आप वास्तव में a\r\n टाइप कर रहे हैं।

जब कोड System.in.read() चलाया जाता है, तो यह इस मामले में a में केवल पहले वर्ण को बफर में दर्ज किया गया है। फिर लूप चलता है, आपके प्रॉम्प्ट को प्रिंट करता है और बफर पर अगले चरित्र को पढ़ने की कोशिश करता है। इस मामले में \r\n अभी भी बफर पर है, इसलिए यह \r में पढ़ता है। लूप्स फिर से और यह \n में पढ़ता है। बफर खाली होने के बाद अंततः यह तीसरे बार प्रॉम्प्ट प्रिंट करता है, यह आपके इनपुट की प्रतीक्षा करता है।

इससे बचने के लिए मैं System.In की बजाय कमांड लाइन से पढ़ने के लिए एक अलग विधि का उपयोग करने का सुझाव दूंगा। शायद Scanner कक्षा अधिक उपयुक्त होगी।

+0

यह लगभग सही है, सिवाय इसके कि पाठ पात्रों को वापस नहीं करते हैं; यह बाइट्स देता है। यदि आप एक गैर-ASCII वर्ण दर्ज करते हैं, तो यह डिफ़ॉल्ट एन्कोडिंग के आधार पर शायद लगातार दो मान लौटाएगा। –

1

एक चीज आपको अवगत होना है कि System.in.read() केवल इनपुट के 1 बाइट लेता है। दस्तावेज़ here देखें।तो जब आप एक चरित्र a दर्ज करते हैं, जो पहले से ही एक बाइट, है में प्रवेश करने के लिए एक अतिरिक्त ENTER द्वारा कुंजी, वर्ण: \r और \n, कि read() दो बार, जो अतिरिक्त पाश यात्रा और प्रिंट तर्क से चलाता है द्वारा कब्जा कर लिया हो जाएगा।

0

जैसा कि @ कोसोबैन ने कहा कि वे एक, सीआर और एलएफ हैं। यह 3 बार दोहरा रहा है, लेकिन यह ओएस के अनुसार बदल जाएगा। इसलिए मैं आपको स्कैनर का उपयोग करने की सलाह देता हूं। आप नीचे

public class DW { 
    public static void main (String args[]) throws java.io.IOException { 
     String s; 
     Scanner scanner = new Scanner(System.in); 
     do { 
      System.out.println("Please a key followed by ENTER:"); 
      s = scanner.nextLine(); 
     } while (!"q".equals(s)); 
     } 
    } 
संबंधित मुद्दे