2009-08-24 19 views
27

मुझे एहसास है कि इस सवाल को अतीत में कई बार पूछा जा सकता है, लेकिन मैं इस पर ध्यान दिए बिना जारी रहूंगा।स्ट्रिंग कनवर्ट करें जिसमें कई संख्याएं पूर्णांक में हैं

मेरे पास एक प्रोग्राम है जो कुंजीपटल इनपुट से संख्याओं की एक स्ट्रिंग प्राप्त करने जा रहा है। संख्या हमेशा "66 33 9" रूप में होगी, अनिवार्य रूप से, प्रत्येक संख्या को एक स्थान से अलग किया जाता है, और उपयोगकर्ता इनपुट में हमेशा अलग-अलग संख्याएं होती हैं।

मुझे पता है कि 'sscanf' का उपयोग करना होगा यदि प्रत्येक उपयोगकर्ता द्वारा दर्ज स्ट्रिंग में संख्याओं की संख्या स्थिर थी, लेकिन यह मेरे लिए मामला नहीं है। इसके अलावा, क्योंकि मैं सी ++ में नया हूं, मैं वर्णों के सरणी के बजाय 'स्ट्रिंग' चर से निपटना पसंद करूंगा।

+6

आईएमओ आम तौर पर 'std :: स्ट्राइक पसंद करते हैं कच्चे चरित्र बफर पर ng' "newbieness" का संकेत नहीं है, बल्कि परिपक्वता के बजाय। – sbi

उत्तर

29

मुझे लगता है कि आप एक पूरी लाइन पढ़ना चाहते हैं, और इनपुट के रूप में पार्स करना चाहते हैं।

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

अब डाल एक stringstream में है कि:: तो, पहली पंक्ति हड़पने

std::stringstream stream(input); 

और पार्स

while(1) { 
    int n; 
    stream >> n; 
    if(!stream) 
     break; 
    std::cout << "Found integer: " << n << "\n"; 
} 

शामिल करना न भूलें

#include <string> 
#include <sstream> 
+18

आपका मतलब पार्स: 'int n; जबकि (स्ट्रीम >> एन) {std :: cout << "पूर्णांक मिला:" << n << "\ n";} '? एक बार जब आप 1000 "std ::" s को "एकल नाम का उपयोग कर" के साथ बदलते हैं तो बहुत साफ –

1

Here is अपनी स्ट्रिंग को रिक्त स्थान पर स्ट्रिंग में कैसे विभाजित करें। फिर आप उन्हें एक-एक करके संसाधित कर सकते हैं।

0

पहले स्ट्रिंग को अलग करने के लिए strtoken आज़माएं, फिर आप प्रत्येक स्ट्रिंग से निपटेंगे।

2
#include <string> 
#include <vector> 
#include <sstream> 
#include <iostream> 
using namespace std; 

int ReadNumbers(const string & s, vector <int> & v) { 
    istringstream is(s); 
    int n; 
    while(is >> n) { 
     v.push_back(n); 
    } 
    return v.size(); 
} 

int main() { 
    string s; 
    vector <int> v; 
    getline(cin, s); 
    ReadNumbers(s, v); 
    for (int i = 0; i < v.size(); i++) { 
     cout << "number is " << v[i] << endl; 
    } 
} 
8
#include <string> 
#include <vector> 
#include <iterator> 
#include <sstream> 
#include <iostream> 

int main() { 
    std::string input; 
    while (std::getline(std::cin, input)) 
    { 
     std::vector<int> inputs; 
     std::istringstream in(input); 
     std::copy(std::istream_iterator<int>(in), std::istream_iterator<int>(), 
     std::back_inserter(inputs)); 

     // Log process: 
     std::cout << "Read " << inputs.size() << " integers from string '" 
     << input << "'" << std::endl; 
     std::cout << "\tvalues: "; 
     std::copy(inputs.begin(), inputs.end(), 
     std::ostream_iterator<int>(std::cout, " ")); 
     std::cout << std::endl; 
    } 
} 
+3

+1 " और आपको आवश्यक हेडर का जिक्र करें। –

+5

+1 जब तक आप 'std ::' उपसर्ग रखते हैं। उनकी पठनीयता एक व्यक्तिपरक है (मैं, उनके लिए उपयोग किया जा रहा है, इसे पढ़ने के लिए बेहतर लगता है), लेकिन पूरी तरह से योग्य नामों के माध्यम से बढ़ी स्पष्टता उद्देश्य है। 'नामस्थान का उपयोग कर' के साथ बदलने के बाद – sbi

+0

+1। फिर आप किसी अन्य के साथ कार्यान्वयन को प्रतिस्थापित कर सकते हैं, और नामस्थान बदलने के साथ सामना करने की आवश्यकता नहीं है। – nothrow

1
// get string 
std::string input_str; 
std::getline(std::cin, input_str); 

// convert to a stream 
std::stringstream in(input_str); 

// convert to vector of ints 
std::vector<int> ints; 
copy(std::istream_iterator<int, char>(in), std::istream_iterator<int, char>(), back_inserter(ints)); 
1

अहस्ताक्षरित मूल्यों (उपसर्ग के साथ काम '-' एक अतिरिक्त bool लेता है) के लिए जेनेरिक समाधान:

template<typename InIter, typename OutIter> 
void ConvertNumbers(InIter begin, InIter end, OutIter out) 
{ 
    typename OutIter::value_type accum = 0; 
    for(; begin != end; ++begin) 
    { 
     typename InIter::value_type c = *begin; 
     if (c==' ') { 
      *out++ = accum; accum = 0; break; 
     } else if (c>='0' && c <='9') { 
      accum *= 10; accum += c-'0'; 
     } 
    } 
    *out++ = accum; 
     // Dealing with the last number is slightly complicated because it 
     // could be considered wrong for "1 2 " (produces 1 2 0) but that's similar 
     // to "1 2" which produces 1 0 2. For either case, determine if that worries 
     // you. If so: Add an extra bool for state, which is set by the first digit, 
     // reset by space, and tested before doing *out++=accum. 
} 
+0

+1 क्योंकि आप बताए गए प्रश्न का उत्तर देते हैं ("पूर्णांक"), लेकिन मुझे लगता है कि यह वास्तव में कुछ मामलों में कम-सामान्य दिशा में एक कदम है, क्योंकि यह होगा स्पष्ट रूप से केवल पूर्णांक के लिए काम करते हैं और अन्य प्रकारों के नहीं (IOW: "टाइपनाम आउटइटर :: value_type accum = 0;" की "जेनेरिकिटी" अतिस्तरीय है)। उदाहरण के लिए आप फ़्लोटिंग पॉइंट नंबर कैसे संभालेंगे? यदि आप एक और मिनी लेक्सर लिखना चाहते हैं, तो वैज्ञानिक नोटेशन और इंफ, नाएन इत्यादि को संभालना न भूलें –

+0

ठीक है, यह 'छोटा [] ',' std :: वेक्टर 'और' std :: list स्वीकार करेगा या वास्तव में किसी भी अन्य अभिन्न प्रकार (कार्यान्वयन-परिभाषित प्रकार सहित)। सादा 0 उन सभी में परिवर्तित हो जाएगा। जिस कारण से मैंने वैल्यूएट टाइप का उपयोग किया है, इसलिए मैं गलती से 'int' ओवरफ्लो नहीं करूँगा जब उपयोगकर्ता '__int128 []' और बड़ी संख्या वाले स्ट्रिंग के रूप में गुजरता है। – MSalters

+0

accum के लिए value_type का उपयोग करने का बिल्कुल सही तरीका है, लेकिन मुझे लगता है कि मुझे नहीं लगता कि आप अपने हस्तशिल्प लेक्सर के बजाय केवल एक इस्ट्रिंगस्ट्रीम का उपयोग क्यों नहीं कर सकते। फिर आप अपने वर्तमान समाधान की "iteratorwise" जेनेरिकिटी को बलि किए बिना ऑपरेटर <<() (यानी "इसी तरह" सामान्यता) में सुधार किए गए किसी भी प्रकार के साथ काम कर सकते हैं। मुझे यह भी संदेह है कि व्यापक वर्ण, लोकेशन इत्यादि के साथ काम करने की अधिक संभावना है। –

18

C++ String Toolkit Library (Strtk) है आपकी समस्या के लिए निम्न समाधान:

#include <iostream> 
#include <string> 
#include <deque> 
#include <algorithm> 
#include <iterator> 

#include "strtk.hpp" 

int main() 
{ 
    std::string s = "1 23 456 7890"; 

    std::deque<int> int_list; 
    strtk::parse(s," ",int_list); 

    std::copy(int_list.begin(), 
      int_list.end(), 
      std::ostream_iterator<int>(std::cout,"\t")); 

    return 0; 
} 

अधिक उदाहरण Here

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