2010-03-21 13 views
54

std::cout का उपयोग करते समय प्रिंट करने के लिए पाठ को संरेखित करने का कोई तरीका है? मैं टैब का उपयोग कर रहा हूं, लेकिन जब शब्द बहुत बड़े होते हैं तो उन्हें अब गठबंधन नहीं किया जाएगा।सी ++ संरेखण मुद्रण करते समय संरेखण <<

Sales Report for September 15, 2010 
Artist Title Price Genre Disc Sale Tax Cash 
Merle Blue 12.99 Country 4% 12.47 1.01 13.48 
Richard Music 8.49 Classical 8% 7.81 0.66 8.47 
Paula Shut 8.49 Classical 8% 7.81 0.72 8.49 
+2

नीचे दिए गए प्रतिसाद कॉलम की चौड़ाई निर्दिष्ट करने की अनुमति देते हैं। ध्यान दें कि इसके लिए आपको ऊपरी बाउंड (उदाहरण के लिए डेटाबेस बाधा) जानने या इसे पहले से गणना करने की आवश्यकता है (जिसका मतलब है कि वास्तव में प्रिंट करने से पहले पूरी संरचना को पार्स करना)। दूसरा, यद्यपि आवश्यक है, निश्चित रूप से धीमा है :) –

उत्तर

7

setw मैनिपुलेटर फ़ंक्शन यहां सहायता करेगा।

+3

आपको 'बाएं' और 'दाएं' का भी उल्लेख करना चाहिए जो संरेखण और 'सेटफिल' निर्दिष्ट करने की अनुमति देता है जो निर्दिष्ट करने के लिए अनुमति देता है कि कौन सा चरित्र पूरा हो रहा है (डिफ़ॉल्ट रूप से स्थान)। –

8

आईओ मैनिपुलेटर जो आपको चाहिए। विशेष रूप से setw। यहाँ संदर्भ पृष्ठ से एक उदाहरण है:

// setw example 
#include <iostream> 
#include <iomanip> 
using namespace std; 

int main() { 
    cout << setw (10); 
    cout << 77 << endl; 
    return 0; 
} 

बाईं ओर क्षेत्र को सही ठहराते हैं और सही left और right manipulators साथ किया जाता है।

setfill पर भी एक नज़र डालें। formatting C++ output with io manipulators पर एक और पूर्ण ट्यूटोरियल है।

4

बार जब आप बहुत पहली पंक्ति का उत्सर्जन में

Artist Title Price Genre Disc Sale Tax Cash 

"संरेखण", आप "पहले से" पता करने के लिए है कैसे विस्तृत प्रत्येक स्तंभ होने की आवश्यकता होगी प्राप्त करने के लिए (अन्यथा, संरेखण असंभव है) । एक बार जब आप प्रत्येक कॉलम के लिए आवश्यक चौड़ाई को जानते हैं (यह प्राप्त करने के कई तरीके हैं कि आपका डेटा कहां से आ रहा है), तो दूसरे उत्तर में उल्लिखित setw फ़ंक्शन मदद करेगा, या (अधिक क्रूरता से ;-) अतिरिक्त रिक्त स्थान (क्लंकी, सुनिश्चित करने के लिए) की ध्यान से गणना की गई संख्या को उत्सर्जित कर सकते हैं, आदि। मैं वैसे भी टैब की अनुशंसा नहीं करता क्योंकि आपके पास वास्तविक आउटपुट डिवाइस सामान्य रूप से प्रस्तुत करने के तरीके पर कोई वास्तविक नियंत्रण नहीं है।

मूल समस्या पर वापस जाएं, यदि आपके पास प्रत्येक कॉलम का मान vector<T> में किसी प्रकार का है, उदाहरण के लिए, आप कॉलम की अधिकतम चौड़ाई निर्धारित करने के लिए पहला प्रारूपण पास कर सकते हैं, उदाहरण के लिए (सुनिश्चित करना सुनिश्चित करें कॉलम के लिए हेडर की चौड़ाई भी, ज़ाहिर है)।

यदि आपकी पंक्तियां "एक-एक करके" आ रही हैं, और संरेखण महत्वपूर्ण है, तो आपको पंक्तियों को कैश या बफर करना होगा क्योंकि वे अंदर आते हैं (स्मृति में अगर वे फिट होते हैं, अन्यथा डिस्क फ़ाइल पर बाद में "रिवाइंड" और शुरुआत से दोबारा पढ़ा जाए), पंक्तियों के आने के बाद "प्रत्येक कॉलम की अधिकतम चौड़ाई" के वेक्टर को अद्यतन रखने के लिए देखभाल करना। आप कुछ भी आउटपुट नहीं कर सकते हैं (यहां तक ​​कि हेडर भी नहीं!), अगर संरेखण रखना महत्वपूर्ण है, तब तक जब तक कि आपने आखिरी पंक्ति नहीं देखी है (जब तक कि आप किसी भी तरह से जादुई रूप से स्तंभों की चौड़ाई का पिछला ज्ञान नहीं रखते हैं ;-)।

112

आईएसओ सी ++ मानक तरीका यह करने के लिए #include <iomanip> है और std::setw जैसे आईओ मैनिपुलेटर्स का उपयोग करें। हालांकि, उन्होंने कहा, उन io manipulators पाठ के लिए भी उपयोग करने के लिए एक असली दर्द हैं, और प्रारूपण संख्याओं के लिए बस अनुपयोगी हैं (मुझे लगता है कि आप चाहते हैं कि आपके डॉलर की मात्रा दशमलव पर लाइन हो, महत्वपूर्ण अंकों की सही संख्या हो, आदि ।)। यहां तक ​​कि सिर्फ सादा पाठ लेबल के लिए, कोड अपने पहली पंक्ति के पहले भाग के लिए कुछ इस तरह दिखेगा:

// using standard iomanip facilities 
cout << setw(20) << "Artist" 
    << setw(20) << "Title" 
    << setw(8) << "Price"; 
// ... not going to try to write the numeric formatting... 

आप Boost libraries, चलाने का उपयोग करने में सक्षम हैं (चलना नहीं है) और का उपयोग Boost.Format लाइब्रेरी इसके बजाए। यह मानक iostreams के साथ पूरी तरह से संगत है, और यह आपको printf/Posix स्वरूपण स्ट्रिंग के साथ आसान स्वरूपण के लिए सभी भलाई देता है, लेकिन iostreams की किसी भी शक्ति और सुविधा को खोए बिना।

// using Boost.Format 
cout << format("%-20s %-20s %-8s\n") % "Artist" % "Title" % "Price"; 
cout << format("%-20s %-20s %8.2f\n") % "Merle" % "Blue" % 12.99; 
+5

बूस्ट.फॉर्मेट असली अच्छा है :) –

+2

'बूस्ट.फॉर्मैट' बहुत अच्छा लग रहा है। टाइप-सुरक्षा के साथ सीधे 'printf'-style formatting। – dreamlax

+4

पोजिशनल प्रारूप भी, जो कि बहुत अच्छा है, इसका मतलब है कि आप उन्हें स्थानीयकरण फ़ाइल से खींच सकते हैं। –

9

यह भी देखें:: Which C I/O library should be used in C++ code?

struct Item 
{ 
    std::string  artist; 
    std::string  c; 
    integer   price; // in cents (as floating point is not acurate) 
    std::string  Genre; 
    integer   disc; 
    integer   sale; 
    integer   tax; 
}; 

std::cout << "Sales Report for September 15, 2010\n" 
      << "Artist Title Price Genre Disc Sale Tax Cash\n"; 
FOREACH(Item loop,data) 
{ 
    fprintf(stdout,"%8s%8s%8.2f%7s%1s%8.2f%8.2f\n", 
      , loop.artist 
      , loop.title 
      , loop.price/100.0 
      , loop.Genre 
      , loop.disc , "%" 
      , loop.sale/100.0 
      , loop.tax/100.0); 

    // or 

    std::cout << std::setw(8) << loop.artist 
       << std::setw(8) << loop.title 
       << std::setw(8) << fixed << setprecision(2) << loop.price/100.0 
       << std::setw(8) << loop.Genre 
       << std::setw(7) << loop.disc << std::setw(1) << "%" 
       << std::setw(8) << fixed << setprecision(2) << loop.sale/100.0 
       << std::setw(8) << fixed << setprecision(2) << loop.tax/100.0 
       << "\n"; 

    // or 

    std::cout << boost::format("%8s%8s%8.2f%7s%1s%8.2f%8.2f\n") 
       % loop.artist 
       % loop.title 
       % loop.price/100.0 
       % loop.Genre 
       % loop.disc % "%" 
       % loop.sale/100.0 
       % loop.tax/100.0; 
} 
5

गठबंधन स्तंभ है इस प्रकार बनाने के लिए एक और तरीका है: उदाहरण के लिए, अपने पहले दो पंक्तियों के पहले भागों कुछ ऐसा दिखाई देगा

using namespace std; 

cout.width(20); cout << left << "Artist"; 
cout.width(20); cout << left << "Title"; 
cout.width(10); cout << left << "Price"; 
... 
cout.width(20); cout << left << artist; 
cout.width(20); cout << left << title; 
cout.width(10); cout << left << price; 

हमें प्रत्येक कॉलम के लिए अधिकतम मानों का अनुमान लगाया जाना चाहिए। इस मामले में, "कलाकार" कॉलम के मान 20 वर्णों से अधिक नहीं होनी चाहिए और इसी तरह।

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