2010-07-23 12 views
19

पर कॉल करने से पहले डेटा उपलब्धता की जांच करना मैं std::getline का उपयोग कर स्ट्रीम से कुछ डेटा पढ़ना चाहता हूं। std::cin का उपयोग कर नमूना के नीचे।std :: getline

std::string line; 
std::getline(std::cin, line); 

यह एक अवरुद्ध कार्य है यानी अगर इसे पढ़ने के लिए कोई डेटा या रेखा नहीं है तो इसे निष्पादन अवरुद्ध करता है।

क्या आप जानते हैं कि std::getline पर कॉल करने से पहले डेटा उपलब्धता की जांच करने के लिए कोई फ़ंक्शन मौजूद है या नहीं? मैं ब्लॉक नहीं करना चाहता।

मैं कैसे जांच सकता हूं कि स्ट्रीम बफर std::getline पर सफल कॉल के लिए मान्य डेटा से भरा है या नहीं?

जो भी नीचे

if(dataAvailableInStream()) 
{ 
    std::string line; 
    std::getline(std::cin, line); 
} 
+1

आप कहते हैं कि आप ब्लॉक नहीं करना चाहते हैं, लेकिन आपका उदाहरण std :: cin का उपयोग करता है। हमें बताएं कि आप क्या हासिल करने की कोशिश कर रहे हैं और शायद हम अपने उत्तर को अधिक सहायक होने के लिए स्पष्ट कर सकते हैं। – nathan

+0

हाय सब! मेरे पास अवरुद्ध आईट्रीम है। विशिष्ट में मैं प्रक्रियाओं के लिए POCO लाइब्रेरी का उपयोग कर रहा हूं और मैं POCO :: PipeInputStream से पढ़ना चाहता हूं। मेरा प्रश्न था: 1. मुझे पता है कि ब्लॉकिंग स्ट्रीम के साथ std :: getline को कॉल करने से कोई डेटा उपलब्ध नहीं होगा 2. डेटा उपलब्ध है या नहीं, यह जांचने के लिए कॉल करने के लिए कौन सा फ़ंक्शन 3. यदि कोई डेटा उपलब्ध नहीं है तो मैं हूं क्योंकि यह ब्लॉक –

+0

(यह अभी भी खोज परिणामों में पता चलता है।) एसटीडी कॉल करने के लिए नहीं जा रहा :: getline मेरा उत्तर यहाँ देखें: http://stackoverflow.com/a/42264216/1599699 – Andrew

उत्तर

8

iostream पुस्तकालय गैर अवरुद्ध I/O की अवधारणा का समर्थन नहीं करता। मुझे नहीं लगता कि सी ++ मानक में कुछ भी है जो करता है। कोई भी अच्छा समाधान प्लेटफार्म-विशिष्ट होगा। यदि आप POSIX पुस्तकालयों का उपयोग कर सकते हैं, तो आप select देख सकते हैं। यह आमतौर पर नेटवर्किंग सामान के लिए उपयोग किया जाता है, लेकिन अगर आप इसे stdin के लिए फ़ाइल डिस्क्रिप्टर पास करते हैं तो यह ठीक काम करेगा।

-2

std :: iostream कोड की तरह दिखता है एक झलक समारोह है कि इसे हटाने के बिना धारा में अगले वर्ण देता है प्रदान करता है। तो आप निम्न की तरह कुछ कर सकते हैं (पूरी तरह से परीक्षण नहीं किया गया)।

bool dataAvailableInStream(std::iostream &stream) 
{ 
    return stream.peek() != std::iostream::traits_type::eof(); 
} 

संपादित

rubenvb बताते हैं के रूप में, std::cin डिजाइन द्वारा ब्लॉक। इसलिए उपर्युक्त कोड आपको getline अवरुद्ध कर देगा, लेकिन cin नहीं।

संपादित करें संपादित करें

चार्ल्स नीचे बताते हैं के रूप में, peek ब्लॉक करता है, तो कोई डेटा उपलब्ध है। इसलिए यह एक पूर्ण समाधान प्रदान नहीं करता है। यह आपको getline पर अवरुद्ध करने से रोक देगा, लेकिन समग्र रूप से अवरुद्ध नहीं होगा।

+1

या 'वापसी stream.peek()! = std :: eof; 'यदि आप verbosity में नहीं हैं। –

+0

@ माइक लॉल। मैं इसे आपके कार्यान्वयन को दर्शाने के लिए संपादित करूंगा। – nathan

+4

यह काम नहीं करता है! मैंने कोशिश की और peek() ब्लॉक के रूप में std :: getline() करता है जब पढ़ने के लिए कुछ भी नहीं है। –

0

हालांकि नाथन के peek() उत्तर देखेंगे कि डेटा है या नहीं, इस बात की कोई गारंटी नहीं है कि std::getline() "लाइन" पढ़ने में सफल होगा।

यह हमेशा बहुत आसान यद्यपि थोड़ा पीछे की ओर getline कोशिश करते हैं और तुमको फ़ंक्शन के परिणाम की जाँच करने में ही फोन है: (यानी निकालने और में जगह कर सकते हैं

std::string line; 
while(!std::getline(std::cin, line)) 
{ 
    cout << "Enter something please" << endl; 
} 

तक cin कुछ यह पसंद करती है प्राप्त करता है यह कोड चलेंगे line)। मुझे peek() यहां आवश्यक या उपयोगी नहीं दिख रहा है।

संपादित करें: बात यह है कि cin (== मानक कीबोर्ड इनपुट) प्रोग्राम को ब्लॉक करना होगा क्योंकि यह इनपुट के लिए इंतजार कर रहा है, यह इंतजार नहीं करेगा जब यह कोई इनपुट प्राप्त नहीं कर सकता है?

+0

सीन के बारे में अच्छा बिंदु, मैंने नहीं सोचा था कि यह अवरुद्ध होगा। – nathan

15

getline ब्लॉक करेगा या नहीं, यह सत्यापित करने का कोई मानक तरीका नहीं है। आप उपयोग कर सकते हैं:

std::cin.rdbuf()->in_avail() 

कितने वर्ण निश्चित रूप से उपलब्ध होने से पहले पढ़ने आपरेशन ब्लॉक कर सकते हैं कर रहे हैं देखने के लिए है, लेकिन आप पात्रों को फिर से जाँच in_avail के रूप में वहाँ कोई रास्ता नहीं में पता करने के लिए है से पहले एक के बाद एक को पढ़ने के लिए होता है अग्रिम अगर लंबित वर्णों में से कोई एक नई लाइन या स्ट्रीम का वास्तविक अंत है। getline कॉल अगर ब्लॉक नहीं हो तो ब्लॉक हो सकता है।

ध्यान दें कि यद्यपि in_avail() एक पोस्टिव नंबर देता है तो गारंटी है कि कम से कम कई वर्ण धारा के अंत से पहले उपलब्ध हैं, बातचीत सच नहीं है। यदि in_avail() शून्य लौटाता है तो अभी भी वर्ण उपलब्ध हो सकते हैं और स्ट्रीम तुरंत अवरुद्ध नहीं हो सकती है।

+2

यह एमएसवीसी 2013 के साथ बहुत अच्छी तरह से काम नहीं करता है। ऐसा लगता है कि स्ट्रीम बंद नहीं होने पर भी कोई सकारात्मक मूल्य वापस नहीं आता है और कोई इनपुट उपलब्ध नहीं है। मैं इसे एक दिन बर्बाद नहीं करूँगा, लेकिन मुझे यकीन है कि यह सड़ा हुआ है। –

+4

"मुझे निश्चित रूप से लगता है कि यह सड़ा हुआ है।" - क्या, एमएसवीसी? ;-) – DevSolar

0

क्या समस्या आप पढ़ने के लिए यहाँ अवरुद्ध से बचने के हल करने की कोशिश कर रहे हैं?

गैर-पोर्टेबल मुझे लगता है कि आप poll या select का उपयोग यह देखने के लिए कर सकते हैं कि stdin पर पढ़ने के लिए डेटा है (अक्सर यूनिक्स सिस्टम पर fd 0)।

वैकल्पिक रूप से आप आई/ओ करने के लिए एक दूसरे धागा बना सकते हैं और इसे ब्लॉक ताकि आप मुख्य थ्रेड में सामान्य प्रोसेसिंग जारी कर सकता है।

+1

यदि मैं दूसरे धागे का उपयोग करता हूं, तो मुझे पता है कि थ्रेड को मारने में समस्या है, इसलिए आवेदन के अंत तक इसे जीने के लिए बेहतर है। क्या यह समझ में आता है? –

1

एक हैक() पढ़ने से पहले kbhit कॉल करने के लिए हो सकता है। शायद पोर्टेबल और खतरे से भरा नहीं ...

#include <conio.h> 
#include <iostream> 

using namespace std; 


char buffer[128]; 

if (kbhit()) 
{ 
    cin.getline(buffer, sizeof(buffer)); 
} 
2

इस कोड को आप को रोके बिना stdin में डेटा के अस्तित्व की जाँच करने में मदद कर सकते हैं:

std::cin.seekg(0, std::cin.end); 
int length = std::cin.tellg(); 
if (length < 0) return; //- no chars available 

तो stdin कुछ डेटा है - मत भूलना स्थिति को शुरुआत में सेट करने के लिए।

std::cin.seekg(0, std::cin.beg); 

फिर आप सहित सभी डेटा पढ़ सकते हैं \0 बफर के अंत में (एक से अधिक हो सकता है):

std::vector<char> s(length); 
std::cin.read(s.data(), length); 

या लाइन द्वारा लाइन:

std::string line; 
while (std::cin) { 
    std::getline(std::cin, line); 
    //..... 
} 

इस कोड एमएसवीसी और जीसीसी (उबंटू) में काम करता है

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