2009-08-26 6 views
37

मैं ऐसा ही कुछ काम करेगा मेरी टर्मिनल आवेदन के लिए एक प्रगति बार बनाना चाहते:कैसे पुनर्मुद्रित बिना टर्मिनल में एक मुद्रित संदेश अद्यतन करने के लिए (लिनक्स)

[XXXXXXX  ] 

जो कितना समय का एक दृश्य संकेत देना होगा प्रक्रिया पूरी होने से पहले छोड़ दिया गया है।

मैं जानता हूँ कि मैं अधिक से अधिक एक्स के मुद्रण बस printf स्ट्रिंग के लिए उन्हें जोड़ने के लिए और फिर से की तरह कुछ कर सकते हैं, लेकिन वह ऐसा दिखाई देगा:

[XXXXXXX  ] 
[XXXXXXXX  ] 
[XXXXXXXXX  ] 
[XXXXXXXXXX ] 

या ऐसा ही कुछ (जाहिर है आप के साथ खेल सकते हैं अंतराल।) लेकिन यह दृष्टि से सौंदर्य नहीं है। पुनर्निर्मित किए बिना नए पाठ के साथ टर्मिनल में मुद्रित पाठ को अपडेट करने का कोई तरीका है? यह सब लिनक्स, सी ++ के तहत है।

उत्तर

40

नया "संस्करण" प्रिंट करते समय \n के बजाय \r का उपयोग करने का प्रयास करें।

for(int i=0;i<=100;++i) printf("\r[%3d%%]",i); 
printf("\n"); 
+0

एक आकर्षण की तरह काम करता है, धन्यवाद – ldog

8

मैं कहूंगा कि एनसीआरएस जैसी लाइब्रेरी ऐसी चीजों के लिए उपयोग की जाएगी। श्राप स्क्रीन के चारों ओर कर्सर को स्थानांतरित करने और पाठ और इस तरह आकर्षित करने में मदद करता है।

NCurses

+6

यहां एक ओवरकिल की तरह लगता है। –

+1

हाँ, शायद ... अगर कोई भविष्य में अधिक फैंसी प्राप्त करना चाहता है तो बस एक सुझाव;) – KFro

+3

हाँ ... प्रगति पट्टी की प्रतीक्षा करते समय पोंग का एक खेल चल रहा है। : डी – kjfletch

6

कुछ इस तरह:

std::stringstream out; 
for (int i = 0; i< 10; i++) 
{ 
    out << "X"; 
    cout << "\r" << "[" << out.str() << "]"; 
} 

डरपोक बिट गाड़ी वापसी चरित्र है "\ r" जो अगले करने के लिए नीचे जा रहा बिना लाइन के शुरू होने से स्थानांतरित करने के लिए कर्सर का कारण बनता है लाइन।

1

'\ r' कैरिज रिटर्न करेगा। एक लाइनफेड ('\ n') के बिना कैरिज रिटर्न करने वाले प्रिंटर की कल्पना करें। यह लेखन बिंदु को लाइन की शुरुआत में वापस कर देगा ... फिर मूल पंक्ति के शीर्ष पर अपनी अपडेट की गई स्थिति को फिर से मुद्रित करें।

1

यह एक अलग भाषा है, लेकिन this question आपके लिए सहायता की जा सकती है। असल में, बचने वाला चरित्र \ r (कैरिज रिटर्न, \ n न्यूलाइन के विपरीत) आपको अपनी वर्तमान मुद्रित रेखा की शुरुआत में वापस ले जाता है ताकि आप जो पहले से मुद्रित कर चुके हैं उसे ओवरराइट कर सकें।

1

एक और विकल्प एक समय में एक चरित्र को मुद्रित करना है। आमतौर पर, stdout लाइन, बफ़र है, ताकि आप fflush (stdout) कॉल करने के लिए की आवश्यकता होगी -

for(int i = 0; i < 50; ++i) { 
    putchar('X'); fflush(stdout); 
    /* do some stuff here */ 
} 
putchar('\n'); 

लेकिन यह अच्छा समाप्त "]" है कि पूरा होने को इंगित करता है नहीं है।

3

अन्य ने पहले ही बताया है कि आप मौजूदा लाइन की शुरुआत में वापस जाने के लिए \r का उपयोग कर सकते हैं और संपूर्ण लाइन को ओवरराइट कर सकते हैं।

कुछ और जगहों को मिटाने के लिए बैकस्पेस वर्ण ("\ b") का उपयोग करने की एक और संभावना है, और केवल उन रिक्त स्थान को ओवरराइट करें। इसमें कुछ फायदे हो सकते हैं। सबसे पहले, यह स्पष्ट रूप से लाइन में सब कुछ पुन: उत्पन्न करने से बचाता है, जो कभी-कभी हल्के दर्दनाक हो सकता है (हालांकि यह काफी असामान्य है)। दूसरा, यह डेटा प्रदर्शित करने में कुछ दर्द से बच सकता है (उदाहरण के लिए) आकार में घटते समय आप इसे लिखते हैं - उदाहरण के लिए, यदि आप \r के साथ 100 से 0 तक गिनती दिखा रहे हैं, तो आपको सावधान रहना होगा पूरी पिछली लंबाई को ओवरराइट करना, या आपका उलटी गिनती (उदाहरण के लिए) 100 से 9 0 9 (यानी, पिछले "0" बरकरार छोड़कर) जाएगी।

नोट, हालांकि, एक पंक्ति के भीतर बैक-स्पेस सामान्य रूप से काम करता है, जबकि लाइन की शुरुआत में बैकस्पेस कर्सर/लिखने की स्थिति को पिछली पंक्ति में ले जा सकता है या नहीं। अधिकांश व्यावहारिक उद्देश्यों के लिए, आप केवल एक पंक्ति के भीतर ही स्थानांतरित कर सकते हैं।