2015-10-12 6 views
20

जब मैं एक साथ सी में एक टू-बड़े समारोह डाल रहा था ++ मैंने देखा है कि मैं सी स्ट्रिंग सी में अपरकेस में और सी ++

सी ++ समारोह सी

में अपेक्षित आउटपुट प्राप्त नहीं किया

#include <iostream> 
#include <cctype> 
#include <cstdio> 

void strupp(char* beg) 
{ 
    while (*beg++ = std::toupper(*beg)); 
} 

int main(int charc, char* argv[]) 
{ 
    char a[] = "foobar"; 
    strupp(a); 
    printf("%s\n", a); 
    return 0; 
} 

आउटपुट के रूप में उम्मीद:

FOOBAR 


सी समारोह

#include <ctype.h> 
#include <stdio.h> 
#include <string.h> 

void strupp(char* beg) 
{ 
    while (*beg++ = toupper(*beg)); 
} 

int main(int charc, char* argv[]) 
{ 
    char a[] = "foobar"; 
    strupp(a); 
    printf("%s\n", a); 
    return 0; 
} 

उत्पादन पहले वर्ण लापता

OOBAR 

क्या किसी को पता है कि क्यों परिणाम है, जबकि सी में संकलन छोटा कर दिया जाता है के साथ अपेक्षित परिणाम है?

+5

और यदि आप वास्तव में इसे 'सी ++' में करना चाहते हैं: 'std :: transform (a, a + strlen (ए), ए, std :: toupper); ' – PaulMcKenzie

+0

क्या आप समझा सकते हैं कि आप स्ट्रिंग को अपरकेस में बदलने के लिए क्यों उम्मीद करते थे? विशेष रूप से, आपने बाईं ओर से '=' का मूल्यांकन करने के लिए सही पक्ष की अपेक्षा क्यों की थी? –

+0

मैं उन सभी लोगों का आभारी हूं जिन्होंने फीडबैक दिया और मूल्यवान जानकारी प्रदान की गई –

उत्तर

29

समस्या

while (*beg++ = toupper(*beg)); 

तो हम अपरिभाषित है व्यवहार में कोई अनुक्रम मतलब नहीं है कि है। इस मामले में कंपाइलर क्या कर रहा है beg++ का मूल्यांकन toupper(*beg) से पहले सी में है जहां सी ++ में यह दूसरी तरफ कर रहा है।

+0

क्या इसका मतलब यह है कि क्लासिक सी-स्ट्रिंग एक-लाइनर की प्रतिलिपि बना रहा है, जबकि (* s ++ = * t ++); 'अपरिभाषित व्यवहार है? –

+3

@markh नहीं, क्योंकि यह दो अलग-अलग चर है। यह 'जबकि (* s ++ = * s ++)' – NathanOliver

+0

@SteveJessop वास्तव में, 'जबकि (* s ++ = * t ++) के समानार्थी है; 's == t' के बावजूद व्यवहार परिभाषित किया गया है। ओवरलैपिंग क्षेत्रों के साथ 'strcpy' को अपरिभाषित करने का कारण यह है कि' strcpy' जरूरी नहीं है '* (* s ++ = * t ++); '। – immibis

15
while (*beg++ = std::toupper(*beg)); 

अपरिभाषित व्यवहार की ओर जाता है।

चाहे *beg++std::toupper(*beg) से पहले या उसके बाद अनुक्रमित है, निर्दिष्ट नहीं है।

उन्हें आसानी से ठीक उपयोग करने के लिए है:

while (*beg = std::toupper(*beg)) 
    ++beg; 
10

लाइन

while (*beg++ = toupper(*beg)); 

एक इकाई है कि दो बार इस्तेमाल किया जा रहा है पर एक पक्ष प्रभाव होता है। आप नहीं जान सकते हैं कि + beg ++ (टॉपर के अंदर) के पहले या बाद में निष्पादित किया गया है या नहीं। आप बस भाग्यशाली हैं कि दोनों कार्यान्वयन दोनों व्यवहार दिखाते हैं, क्योंकि मुझे पूरा यकीन है कि यह सी ++ के लिए समान है। (हालांकि, वहाँ ग के लिए कुछ नियम परिवर्तन ++ 11 है, जो मैं के कुछ नहीं कर रहा हूँ थे - फिर भी, यह बुरा शैली है।)

बस बेग ++ ले जाने के हालत से बाहर:

while (*beg = toupper(*beg)) beg++; 
3

साथ उपर्युक्त उत्तर का सम्मान, 'एफ' कभी भी फ़ंक्शन के अंदर पारित नहीं होता है, आपको इसका उपयोग करने का प्रयास करना चाहिए:

 while ((*beg = (char) toupper(*beg))) beg++; 
+0

चार को कास्टिंग महत्वपूर्ण था क्योंकि प्रकार int का मान रिसीवर प्रकार char – vishal

+1

में फिट नहीं हो सकता है कि उस कलाकार को ऐसा कुछ भी नहीं मिलता है जो इसके बिना भी नहीं होगा। – Flexo

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