2011-10-06 12 views
7

मैं कम से कम प्राथमिक त्रुटि पहचान के साथ सी ++ iostream से बेस -10 (दशमलव) प्रतिनिधित्व में हस्ताक्षरित पूर्णांक पढ़ना चाहता हूं। मेरे विचार में, इस मामले में ऋण संकेत स्पष्ट रूप से एक त्रुटि होगी, क्योंकि हस्ताक्षरित पूर्णांक के पास कोई संकेत नहीं है। हालांकि, जीसीसी एक अलग राय है:हस्ताक्षर किए गए पूर्णांक पढ़ने पर नकारात्मक संख्याओं को पार्सिंग त्रुटियों के रूप में कैसे पहचानें?

#include <iostream> 
#include <sstream> 

int main() { 
    std::stringstream a("5"), b("-0"), c("-4"); 
    unsigned int i; 
    a >> i; if (a) std::cout << i << std::endl; else std::cout << "Conversion failure" << std::endl; 
    b >> i; if (b) std::cout << i << std::endl; else std::cout << "Conversion failure" << std::endl; 
    c >> i; if (c) std::cout << i << std::endl; else std::cout << "Conversion failure" << std::endl; 
    return 0; 
} 

मुझे, अंतिम पंक्ति के लिए

4294967292 

के उत्पादन देता है के रूप में अगर एक हस्ताक्षरित पूर्णांक -4 पढ़ा गया था और अहस्ताक्षरित int करने के लिए परिवर्तित।

Appearently, the GCC people see this as a feature। क्या कोई मानक है जो इस व्यवहार को अनिवार्य करता है, और क्या इससे बाहर निकलने के लिए स्वयं को पार्सर लिखने से कोई रास्ता कम है, यानी "-4" (और शायद "-0") को रूपांतरण त्रुटियों के रूप में पहचानें?

+0

क्या आपने सही बग रिपोर्ट पोस्ट की थी? किसी भी प्रतिरोध के बिना उसे "निश्चित" चिह्नित किया जाता है। – spraff

+0

@spraff: ऐसा लगता है, यह नकारात्मक संख्या व्यवहार का उल्लेख करता है। – thiton

उत्तर

4

परामर्श सी ++ 03, 22.2.2.1.2/11, प्रारूप scanf और दोस्तों से विरासत में प्राप्त हुए हैं, जो बदले में कहते हैं कि रूपांतरित वर्ण अनुक्रम "वैकल्पिक रूप से हस्ताक्षरित" है, यहां तक ​​कि हस्ताक्षरित आउटपुट वाले लोगों के लिए भी । strtoul वही है।

तो, मुझे लगता है कि आप मानक कह सकते हैं कि C++ 03 के लिए C89+ C9+ के लिए C89 + C99 के लिए व्यवहार करना आवश्यक है।

चूंकि - को केवल पहले वर्ण के रूप में अनुमति दी जाती है, मुझे लगता है कि operator>> का उपयोग करने से पहले यह कामकाज peek के साथ जांचना है।

-1

यदि आप ऐसा करेंगे तो यह वास्तव में अलग होगा?

int i; 
unsigned int u; 
c >> i; 
u = i; 
std :: cout << u; 

यह बात इतना नहीं कि operator>> हस्ताक्षर बेमेल बर्दाश्त क्योंकि अंतर्निहित सी नियम किसी भी मामले में एक मूक रूपांतरण की अनुमति देगा है। आप मूल रूप से इनपुट ऑपरेटर को "मजबूत" करके कोई सुरक्षा नहीं जोड़ रहे हैं।

जिसके अनुसार, मेरी जीसीसी (4.3.5 सोलारिस) का कहना है कि यह एक रूपांतरण त्रुटि है।

+2

-Wconversion -Wsign-conversion -Werror के साथ संकलन करते समय यह वास्तव में अलग होगा। मैं चुप रूपांतरण बंद कर सकता हूं, लेकिन टूस्ट iostream साइन हैंडलिंग नहीं कर सकता। – thiton

+0

यह संभवतः इसे संभालने का निर्णय लेता है जैसे कि शाब्दिकों को संभाला जाता है, लेकिन मुझे नहीं पता कि मानक इसके बारे में क्या कहता है। –

+0

रूपांतरण त्रुटि एक अच्छी बात है, और ऐसा लगता है क्योंकि आप पुराने जीसीसी संस्करण (पूर्व 4.4.1, बग के अनुसार) का उपयोग करते हैं, जो मुझे अभी भी सोचता है कि जीसीसी लोगों ने कुछ भी ठीक करने का प्रयास क्यों किया। – thiton

0

तो मैंने पढ़ा 22.2.2.1.2/तालिका 5 सही ढंग से यह पता चलता है कि एक अहस्ताक्षरित में निकालने %u जो प्रतीत होता भी नकारात्मक कर साथ scanf के बराबर है -> सकारात्मक रूपांतरण।

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