2015-03-11 6 views
14

के साथ सभी लाइनों मैं कंसोल में एक बहु लाइन पाठ एक BufferedReader का उपयोग कर टाइप करना चाहते हैं पढ़ें और जब मैं हिट पूरे पाठ की लंबाई की राशि को खोजने के लिए "Enter"। समस्या यह है कि ऐसा लगता है कि मैं एक अनंत लूप में जा रहा हूं और जब मैं "एंटर" दबाता हूं तो प्रोग्राम समाप्त नहीं होता है। मेरा कोड नीचे है:BufferedReader

InputStreamReader instream = new InputStreamReader(System.in); 
BufferedReader buffer = new BufferedReader(instream); 

    line= buffer.readLine(); 

    while (line!=null){ 
     length = length + line.length(); 
     line= buffer.readLine(); 
    } 

क्या आप कृपया मुझे बता सकते हैं कि मैं क्या गलत कर रहा हूं?

+4

जब आप केवल एंटर दबाएं 'line' बराबर होगा" "रिक्त नहीं। 'line! = null' को'! line.equals ("") ' – StephenButtolph

+3

में बदलने का प्रयास करें, इसके अलावा, बस कुछ अन्य राय प्रदान करने के लिए (उदाहरण के लिए लूप का उपयोग करना), http://codereview.stackexchange.com/questions/44135/ यह-ठीक-ठीक-उपयोग-जबकि-लाइन-आर-रीडलाइन-नल-निर्माण – Foon

+0

मुझे कल रात एहसास हुआ क्योंकि मैं सो रहा था: आप किसके लिए लंबाई का उपयोग कर रहे हैं? एनबी कि अगर आप बिल्ली myfile करना था | जावा अपप्रोग्राम और लंबाई के मूल्य को प्रिंट करें, इससे असहमत होगा, उदा। डब्ल्यूसी प्रिंट आउट, क्योंकि आप न्यूलाइन की गिनती नहीं कर रहे हैं। यदि आपको ऐसा करने की आवश्यकता है, तो ध्यान दें कि डॉस फ़ाइलों में "\ r \ n" होगा और यूनिक्स फ़ाइलों के पास "\ n" होगा और System.getProperty ("line.separator") का उपयोग करने के लिए मेरा मूल सुझाव शायद काम नहीं करेगा क्योंकि इस बात की कोई गारंटी नहीं है कि आप उदाहरण नहीं हैं लिनक्स के तहत एक डॉस फ़ाइल पढ़ने की कोशिश कर रहा है। (इसलिए, उम्मीद है कि ऐसा करने का मतलब नहीं है) – Foon

उत्तर

19

मुहावरेदार रास्ता: डी संपादित साथ स्मृति से मैं बनाने के लिए जा रहा था। इसके अलावा, मैं एक try-with-resources statement का सुझाव दूंगा।जैसे

try (InputStreamReader instream = new InputStreamReader(System.in); 
     BufferedReader buffer = new BufferedReader(instream)) { 
    long length = 0; 
    String line; 
    while ((line = buffer.readLine()) != null) { 
     length += line.length(); 
    } 
    System.out.println("Read length: " + length); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

आप पाश समाप्त करने के लिए जब आप एक खाली पंक्ति प्राप्त चाहते हैं, while पाश

while ((line = buffer.readLine()) != null) { 
    if (line.isEmpty()) { 
     break; 
    } 
    length += line.length(); 
} 

JLS-14.15. The break Statement में है कि के लिए एक परीक्षण जोड़ने के कुछ कहता है

एक break बयान एक संलग्न बयान से नियंत्रण स्थानांतरित करें।

+0

क्योंकि ओपी 'system.in' से पढ़ रहा है, क्या यह कभी खत्म नहीं होगा? क्या यह सिर्फ उपयोगकर्ताओं के लिए इंतजार नहीं करेगा इनपुट? – StephenButtolph

+1

@StephenB यह ईओएफ (या ctrl-d) पर समाप्त होगा; संभवतः ctrl-c और/या ctrl-brk के साथ भी। –

+2

लेकिन मुझे लगता है कि वह एंटर दबाते समय इसे समाप्त करना चाहता है। – StephenButtolph

3

line अशक्त नहीं होगा जब आप प्रवेश दबाएँ; यह खाली स्ट्रिंग होगा।

क्या BufferedReader JavaDoc readLine() के बारे में कहते हैं की

लें ध्यान दें:

टेक्स्ट की पंक्ति में पढ़ता है। लाइन लाइन ('\ n'), एक कैरिज रिटर्न ('\ r'), या एक कैरिज रिटर्न तुरंत लाइनफेड द्वारा पीछा किया जाता है।

और readLine() रिटर्न:

एक स्ट्रिंग किसी भी लाइन समाप्ति अक्षरों का समावेश नहीं है, या लाइन की सामग्री से युक्त अशक्त यदि धारा के अंत

तक पहुँच गया है तो जब आप [Enter] दबाएं, आप BufferedReader एक नया केवल \n, \r, या \r\n युक्त लाइन दे रहे हैं। इसका मतलब है कि readLine() एक खाली स्ट्रिंग वापस कर देगा।

तो यह बजाय की तरह कुछ प्रयास करें:

InputStreamReader instream = new InputStreamReader(System.in); 
BufferedReader buffer = new BufferedReader(instream); 

line = buffer.readLine(); 

while((line != null) && (!line.isEmpty())){ 
    length = length + line.length(); 
    line = buffer.readLine(); 
} 
+2

मैं गलत हो सकता हूं। लेकिन मुझे नहीं लगता कि लौटे स्ट्रिंग में वास्तव में अंत रेखा वर्ण होता है। यदि यह तब होता है तो 'System.out.println (buffer.readLine());' अंत में एक और पंक्ति होगी? – StephenButtolph

+2

इसके अलावा आप जिस जावाडॉक से जुड़े हैं: * "रिटर्न [...] लाइन की सामग्री, जिसमें किसी लाइन-टर्मिनेशन वर्ण शामिल नहीं हैं" *। – Radiodef

+0

@StephenB और @RadioDef: आह मेरी गलती! तुम दोनों सही हो मैं 'पढ़ा() 'से उलझन में था और कौन जानता है। – dbank

0

Snarky जवाब: आप गलत क्या कर रहे हैं केवल जावा में 2 वस्तुओं पैदा कर रही है कुछ करने के लिए ... अगर आप खोज, तो आप शायद कुछ पा सकते हैं BufferedReader या ExtendedBufferReader इत्यादि का विस्तार करने वाले अधिक वर्ग, और फिर यह वास्तविक एंटरप्राइज़ जावा हो सकता है। अधिक उपयोगी जवाब:

अब जब कि मैं अपने सिस्टम से बाहर है कि मिल गया है

। जब आप इनपुट EOF, जो लिनक्स के तहत नियंत्रण-डी है System.in बंद कर दिया है और मैं MacOS लगता है, और मुझे लगता है कि नियंत्रण-जेड प्लस Windows के तहत दर्ज करें। यदि आप एंटर के लिए जांचना चाहते हैं (या अधिक विशेष रूप से, दो प्रविष्टियां ... एक अंतिम पंक्ति को समाप्त करने के लिए और एक यह इंगित करने के लिए कि आपका काम पूरा हो गया है, जो अनिवार्य रूप से http हैडल निर्धारित करता है कि http शीर्षलेख समाप्त होने पर और यह समय है http शरीर, तो @dbank के समाधान एक छोटी सी ठीक मैं स्थानांतरित करने के लिए बनाने की कोशिश करने जा रहा हूँ के साथ एक व्यवहार्य विकल्प है, जबकि के बजाय जबकि विधेय के अंदर होना चाहिए

(संपादित करें # 2:।! महसूस किया ReadLine न्यू लाइन स्ट्रिप्स, तो एक खाली पंक्ति होगा "" नई पंक्ति के बजाय, इसलिए अब मैं अपने कोड टिप्पणी के बजाय एक जवाब) के रूप में EOF सा के साथ एक और जवाब देने के लिए devolves

संपादित करें ... कि अजीब है, @dbank था जवाब दिया, जबकि मैं अपना जवाब लिख रहा था, और अगर मैंने ईओएफ विकल्प का उल्लेख नहीं किया होता तो मैं रोकता था। अपने सह को दोहराने के लिए पढ़ने के लिए लाइनों के सभी while ((line = buffer.readLine()) != null) है

InputStreamReader instream = new InputStreamReader(System.in); 
BufferedReader buffer = new BufferedReader(instream); 

    line= buffer.readLine(); 
    while (line != null && !line.equals("")){ 
     length = length + line.length(); 
     line= buffer.readLine(); 
    } 
+0

नीचे मतदाता के लिए: यदि यह शीर्ष पर स्नैकी उत्तर की वजह से था, तो बाइट मुझे (मेरा मतलब है, नया बाइट [] ("मुझे" .getBytes (Charset.forName ("UTF-8"))) अन्यथा, मैं उत्सुक हूं कि डाउनवोट्स क्यों: मेरा कोड दूसरों के समान है (और जब मैंने पोस्ट किया था @ डबैंक का जवाब दिखाई दिया, गायब हो गया, और अब फिर से दिखाई दिया; अब आप इसे 9 घंटे के निशान पर नहीं देख सकते हैं, लेकिन मेरा जवाब था दूसरों के सामने मामूली रूप से पोस्ट किया गया) और मैं ईओएफ विकल्प का भी उल्लेख करता हूं (जो पाइपिंग के दौरान भी उपयोगी होता है) – Foon

3

जब आप केवल buffer.readLine(); से वापसी Enter दबाएँ इसे रिक्त स्ट्रिंग है अशक्त नहीं है।

इसलिए आप !line.equals("") को line != null बदलना चाहिए (आप भी line.length() > 0 के लिए इसे बदल सकता है)

अब आप अपने कोड कुछ इस तरह दिखेगा:

InputStreamReader instream = new InputStreamReader(System.in); 
BufferedReader buffer = new BufferedReader(instream); 

line = buffer.readLine(); 

while (!line.equals("")){ 
    length = length + line.length(); 
    line = buffer.readLine(); 
} 

यह आपकी समस्या का समाधान करना चाहिए। उम्मीद है कि यह मदद की! :)

+0

यह वास्तव में काम करता है, लेकिन किसी कारण से मुझे दो बार एंटर दबा देना है। कोई विचार क्यों है? – deadpixels

+0

@deadpixels जब मैं प्रोग्राम चलाता हूं तो यह पहली खाली रेखा पर समाप्त होता है। जब आप एंटर दबाते हैं तो काउंटर ऊपर जाता है? – StephenButtolph

0

जावा 8 के बाद से आप BufferedReader#lines विधि का उपयोग सीधे buffered पाठक पर कर सकते हैं। जावा 8 का उपयोग कर कोड के

try (InputStreamReader in = new InputStreamReader(System.in); 
     BufferedReader buffer = new BufferedReader(in)) { 
     final int length = buffer.lines().mapToInt(String::length).sum(); 
     System.out.println("Read length: " + length); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
28

एक पंक्ति:

line = buffer.lines().collect(Collectors.joining()); 
संबंधित मुद्दे