2010-07-18 11 views
7

मैं एक कार्य निगरानी कोडिंग कर रहा हूं, जो cout का उपयोग कर कार्यों की प्रगति को अद्यतन करता है। मैं प्रति पंक्ति एक कार्य प्रगति प्रदर्शित करना चाहता हूं, इसलिए मुझे कंसोल की कई पंक्तियों को रोलबैक करना होगा।कोउट से रोलबैक लाइनों को कैसे करें?

मैं "कई" पर जोर देता हूं क्योंकि \b एक पंक्ति के लिए नौकरी करता है, लेकिन लाइनों के बीच \n मिटा नहीं देता है।

मैंने std::cout.seekp(std::cout.tellp() - str.length()); की कोशिश की लेकिन tellp() रिटर्न -1 (विफलता)।

+2

आप नहीं कर सकते। 'cout' कंसोल का प्रतिनिधित्व नहीं करता है। यह एक आउटपुट स्ट्रीम का प्रतिनिधित्व करता है। इसका मतलब है कि आप इसे लिख सकते हैं, लेकिन आप पहले से ही लिखे गए कुछ भी नहीं कर सकते हैं। 'cout' प्लेटफॉर्म का उपयोग करने वाले आउटपुट डिवाइस को आउटपुट प्रिंट करने के लिए है (उदाहरण के लिए, लेकिन जरूरी नहीं, एक कंसोल विंडो)। यदि आपको विशेष रूप से कंसोल में हेरफेर करने की आवश्यकता है, तो आपको एक ओएस-विशिष्ट लाइब्रेरी का उपयोग करना होगा जो कंसोल विंडो के बारे में जानता है। – jalf

+1

आप पूर्ण कार्यों की सूची को मिटाना क्यों चाहते हैं? बस प्रति पंक्ति एक कार्य प्रगति आइटम मुद्रित करें, और अगर कोई आपके प्रोग्राम और पाइप को लॉग फ़ाइल में चलाता है तो यह अच्छा होगा। – jamesdlin

+0

मुझे पता है, लेकिन बहुत सारी लाइनें होंगी, मैं उपयोगकर्ता को इंफोस के नीचे डूबना नहीं चाहता हूं, बस उसे स्टेटस दें, और प्रत्येक कार्य के प्रतिशत की प्रगति जो मैं चल रहा हूं। –

उत्तर

16

आप वर्तमान लाइन की शुरुआत में कूदने के लिए cout << '\r'; कर सकते हैं, लेकिन ऊपर की तरफ सिस्टम-विशिष्ट है। यूनिक्स के लिए, man termcap और man terminfo देखें (और cursor_up के लिए खोजें)। एएनएसआई-संगत टर्मिनल पर (जैसे यूनिक्स पर उपलब्ध अधिकांश आधुनिक टर्मिनल), यह बढ़ने के लिए काम करता है: cout << "\e[A";

cout में खोजने का प्रयास न करें, यह ज्यादातर समय अनदेखा है (जब फ़ाइल पर रीडायरेक्ट किया जाता है)।

अन्य उत्तर में उल्लेख किया है, ncurses का उपयोग कर के रूप में (या खिचड़ी) पुस्तकालय के लिए टर्मिनल मैं/यूनिक्स पर हे एक अच्छा अमूर्त प्रदान करता है।

+0

धन्यवाद, मैंने कई लाइनों की निगरानी छोड़ दी, और \ r - 79 जगहों को भर दिया - \ r इसके बजाए। –

8

आउटपुट स्वरूपण लाइब्रेरी का उपयोग करें जैसे कि ncurses यदि आप कर सकते हैं; यह टर्मिनल हेरफेर को काफी सरल बनाता है।

5

न तो सी और न ही सी ++ इस तरह कुछ परिभाषित करता है। आपको स्पष्ट टर्मिनल हेरफेर की आवश्यकता है। यूनिक्स पर आप curses का उपयोग कर सकते हैं। पता नहीं विंडोज के लिए क्या है।

1

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन स्वीकृत उन मामलों को कवर नहीं करता है जहां कार्यक्रम या फ़ाइल में कोउट पाइप किया जाता है और यह मेरी Google खोजों का शीर्ष है। निम्नलिखित थोड़ा अलग व्यवहार के साथ पाइप और गैर-पाइप वाले स्टडआउट दोनों को संभालेगा।

#include <iostream> 
#include <functional> 
#include <stdio.h> 

#ifdef _WIN32 
#include <io.h> 
#else 
#include <unistd.h> 
#define _isatty isatty 
#define _fileno fileno 
#endif 

const std::function<void(const size_t&)> progress_printer(_isatty(_fileno(stdout)) == 1 ? 
    [](const size_t& i) { 
     std::cout << "\rNumber " << i << std::flush; 
    } : 
    [](const size_t& i) { 
     static std::ios::off_type last(-1); 
     if(last != -1) 
      std::cout.seekp(last, std::ios::beg); 
     last = std::cout.tellp(); 
     std::cout << "Number " << i << std::endl; 
    } 
); 

यह विंडोज़ पर अनचाहे है, लेकिन काम करना चाहिए। फ़ाइल डिस्क्रिप्टर या टीटीआई है या नहीं, यह क्या करता है। यदि ऐसा है तो यह केवल '\ r' लिखता है यदि पिछली बार मुद्रित या एक नई लाइन के बाद से pos नहीं बदला है। यदि यह एक नई लाइन नहीं है, तो यह मुद्रित होने के बाद आखिरी जगह की तलाश में है।

यह टीटीई की तुलना में फ़ाइलों के लिए अलग-अलग व्यवहार करता है। एक फ़ाइल के लिए, यदि प्रिंट के बीच स्ट्रीम में कुछ आउटपुट होता है तो यह न्यूलाइन के बाद भी लिखे गए कुछ या सभी को ओवरराइट कर सकता है। Ttys के लिए यह वर्तमान लाइन की शुरुआत में वर्णों को ओवरराइट करता है।

+0

पुराना लेकिन अभी भी सोना – LRP

संबंधित मुद्दे