2011-10-16 11 views
15

नामक कंसोल से इनपुट की प्रतीक्षा नहीं कर रहा है, मैं कंसोल, दो स्ट्रिंग्स, दो इन्ट्स और डबल से कुछ उपयोगकर्ता-इनपुट पैरामीटर प्राप्त करने का प्रयास कर रहा हूं।सी ++ गेटलाइन() कई बार

#include <string> 
#include <iostream> 
using namespace std; 

// ... 

string inputString; 
unsigned int inputUInt; 
double inputDouble; 

// ... 

cout << "Title: "; 
getline(cin, inputString); 
tempDVD.setTitle(inputString); 

cout << "Category: "; 
getline(cin, inputString); 
tempDVD.setCategory(inputString); 

cout << "Duration (minutes): "; 
cin >> inputUInt; 
tempDVD.setDuration(inputUInt); 

cout << "Year: "; 
cin >> inputUInt; 
tempDVD.setYear(inputUInt); 

cout << "Price: $"; 
cin >> inputDouble; 
tempDVD.setPrice(inputDouble); 

हालांकि, जब कार्यक्रम चल रहा है, के बजाय पहले inputString के लिए इंतज़ार कर दर्ज किए जाने की की, कोड दूसरा getline जब तक बंद नहीं() कॉल: प्रासंगिक कोड मैं उपयोग करने के लिए कोशिश कर रहा हूँ यह है । कर्सर श्रेणी के बाद प्रदर्शित होने के साथ

: इस प्रकार सांत्वना उत्पादन इस तरह दिखता है:

शीर्षक: श्रेणी। अगर मैं अब इनपुट करता हूं, तो प्रोग्राम साल के इनपुट तक आगे बढ़ता है, मुझे एक से अधिक स्ट्रिंग में प्रवेश करने की इजाजत नहीं देता है। यहाँ क्या हो रहा है?

+0

पुन: पेश नहीं कर सकते उपयोग करने से पहले

cin.ignore(); 

या के रूप में @kernald उल्लेख उपयोग

cin.clear(); cin.sync(); 

उपयोग कर सकते हैं; असली, पूर्ण कोड पोस्ट करें। मुझे यकीन है कि आपकी समस्या कहीं और है। साथ ही, स्वरूपित इनपुट और 'getline() 'मिश्रण न करें। –

+0

@ केरेकस्क: मैं मानता हूं कि उन्हें मिलाकर खराब शैली का एक लक्षण है, लेकिन उन्हें मिश्रण न करने का उद्देश्य क्या है? मुझे लगता है कि वास्तव में उन्हें मिश्रण करने के लिए यह पूरी तरह से मान्य है। – sehe

+0

@sehe: समस्या यह है कि स्वरूपित निष्कर्षण न्यूलाइन का उपभोग नहीं करता है, इसलिए जब आप पहले से ही सभी पिछली पंक्ति को संसाधित करते हैं, तो यह सोचने के बाद 'getline()' अप्रत्याशित परिणाम प्राप्त करना बहुत आसान होता है। मैं यह नहीं कह रहा कि यह असंभव है, लेकिन यह अक्सर तर्क को पढ़ने और बनाए रखने के लिए तर्क को बहुत कठिन बनाता है। –

उत्तर

16

समस्या आप() ऑपरेटर के उपयोग >> साथ getline के लिए कॉल मिश्रण कर रहे हैं।

याद रखें कि ऑपरेटर >> अग्रणी सफेद स्थान को अनदेखा करता है, इसलिए लाइनों की सीमाओं में सही ढंग से जारी रहेगा। लेकिन इनपुट सफलतापूर्वक पुनर्प्राप्त होने के बाद पढ़ना बंद कर देता है और इस प्रकार पिछली '\ n' वर्णों को निगल नहीं देगा। इस प्रकार यदि आप किसी के बाद एक गेटलाइन() का उपयोग करते हैं, तो आप आमतौर पर गलत चीज प्राप्त करते हैं जब तक कि आप सावधान न हों (पहले '\ n' वर्ण को हटा दें जिसे पढ़ा नहीं गया था)।

चाल दोनों प्रकार के इनपुट का उपयोग नहीं करना है। उपयुक्त एक उठाओ और इसके साथ चिपके रहें।

यदि यह सभी संख्याएं (या ऑब्जेक्ट्स जो ऑपरेटर के साथ अच्छा खेलती हैं >>) तो बस ऑपरेटर >> (नोट स्ट्रिंग एकमात्र मौलिक प्रकार है जो इनपुट/आउटपुट के साथ सममित नहीं है (यानी अच्छी तरह से खेल नहीं है) ।

यदि इनपुट में स्ट्रिंग या सामान का संयोजन होता है जिसके लिए getline() की आवश्यकता होती है तो केवल getline() का उपयोग करें और स्ट्रिंग से संख्या को पार्स करें।

std::getline(std::cin, line); 
std::stringstream linestream(line); 

int value; 
linestream >> value; 

// Or if you have boost: 
std::getline(std::cin, line); 
int value = boost::lexical_cast<int>(line); 
7

आपको इनपुट बफर फ्लश करने की आवश्यकता है। यह cin.clear(); cin.sync(); के साथ किया जा सकता है।

3

उल्लेख और उपयोग उचित त्रुटि हैंडलिंग के रूप में उपयोग cin.clear():

cin.clear(); 
    cin.sync(); 

    cout << "Title: "; 
    if (!getline(cin, inputString)) exit 255; 
    tempDVD.setTitle(inputString); 

    cout << "Category: "; 
    if (!getline(cin, inputString)) exit 255; 
    tempDVD.setCategory(inputString); 

    cout << "Duration (minutes): "; 
    if (!(cin >> inputUInt)) exit 255; 
    tempDVD.setDuration(inputUInt); 

    cout << "Year: "; 
    if (!(cin >> inputUInt)) exit 255; 
    tempDVD.setYear(inputUInt); 

    cout << "Price: $"; 
    if (!(cin >> inputDouble)) exit 255; 
    tempDVD.setPrice(inputDouble); 
+1

धन्यवाद। कोड केवल तभी काम करता है जब दोनों cin.clear() और फिर cin.sync() का उपयोग किया जाता है। – user754852

+0

Getline() विधि के साथ >> ऑपरेटर को मिश्रित करने का सबसे आसान तरीका है cin.ignore() को किसी भी कॉल से पहले कॉल करने से पहले दर्ज करना ताकि इनपुट बफर को पिछले इनपुट से नए लाइन वर्णों पर किसी भी बाएं से साफ़ किया जा सके। –

0

आम तौर पर एक बुरी चीज में इनपुट धाराओं के साथ getline() मिलाकर। धाराओं का उपयोग करके बाईं ओर गंदे बफर को मैन्युअल रूप से संभालना सैद्धांतिक रूप से संभव है, लेकिन यह एक अनावश्यक दर्द है जिसे निश्चित रूप से टाला जाना चाहिए।

आप अपने इनपुट को पकड़ने के लिए कंसोल लाइब्रेरी का उपयोग करना बेहतर कर रहे हैं, इस तरह गंदे काम को आपके लिए सारणित किया जा सकता है।

TinyCon पर एक नज़र डालें। आप अपनी गेटलाइन और स्ट्रीम कॉल की जगह केवल स्थिर विधि tinyConsole :: getLine() का उपयोग कर सकते हैं, और आप इसे जितनी बार चाहें उतनी बार उपयोग कर सकते हैं।

आप यहाँ जानकारी पा सकते हैं: https://sourceforge.net/projects/tinycon/

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