2017-08-04 13 views
12

में केवल एक स्ट्रिंग वैरिएबल नहीं है, तो मेरे पास A, B, C नामक स्ट्रिंग वेरिएबल्स हैं LPCWSTRजांचें कि सी ++

मैं उन्हें किसी अन्य फ़ंक्शन से असाइन कर रहा हूं जो कभी-कभी nullptr लौटा सकता है यदि कुछ गलत हो जाता है। इस तरह:

A = MyFunc(); 
B = MyFunc(); 
C = MyFunc(); 

अब, उन चर के साथ कुछ सामान के लिए, मैं जाँच करने के लिए (केवल चर में से एक असाइन किया गया है) की जरूरत है इन चरों का केवल एक ही nullptr नहीं है।

if ((A == nullptr) && (B == nullptr) && (C <> nullptr)) {} 

कैसे इस स्वागत कर रहे हैं करने के बारे में कोई भी विचार:

मैं इस अपने आप की तरह करने की कोशिश की। nullptr जा रहा है और एक संख्या में भी वृद्धि करता है, तो यह नहीं है के लिए

int not_null = 0; 
not_null += A != nullptr; 
not_null += B != nullptr; 
not_null += C != nullptr; 
if (not_null == 1) { 
    /* Do stuff */ 
} 

चेक प्रत्येक:

+1

क्या आप 'xor' चेन नहीं कर सकते हैं, फिर परिणाम को अस्वीकार कर सकते हैं? कुछ 'जैसे! (ए^बी^सी) '। '^' बिटवाई है, लेकिन यह काम कर सकता है? बस गेंदबाजी थूकना। – Carcigenicate

+0

@ धन्यवाद! लेकिन मैंने कभी भी सी ++ में 'xor' s का उपयोग नहीं किया :-(इसे वैसे भी कोशिश करेंगे। – Blueeyes789

+1

क्या हम मान सकते हैं कि आप परवाह नहीं है कि कौन सा एक शून्य है, क्योंकि एक और केवल एक शून्य है? – user4581301

उत्तर

15

आसान पर्याप्त करने के लिए के साथ:

int numSet = 0; 
A = MyFunc(); if (A != nullptr) numSet++; 
B = MyFunc(); if (B != nullptr) numSet++; 
C = MyFunc(); if (C != nullptr) numSet++; 
if (numSet == 1) // only one is set 

तुम भी एक सहायक समारोह के साथ व्यवहार को संपुटित सकता है:

LPCWSTR MyFuncWithCount(int &countSetProperly) { 
    LPCWSTR retVal = MyFunc(); 
    if (retVal != nullptr) countSetProperly++; 
    return retVal; 
} 

int numSet = 0; 
A = MyFuncWithCount(numSet); 
B = MyFuncWithCount(numSet); 
C = MyFuncWithCount(numSet); 
if (numSet == 1) // only one is set 

अगला कदम वहाँ एक का उपयोग कर किया जाएगा से लूप के लिए रेंज-आधारित के साथ संयोजन में आधारित यह सूची, निम्नलिखित पूरा कार्यक्रम के अनुसार:

#include <iostream> 
#include <vector> 

typedef void * LPCWSTR; // Couldn't be bothered including Windows stuff :-) 

int main() { 
    // Only set two for test purposes. 

    LPCWSTR A = nullptr, B = nullptr, C = nullptr; 
    LPCWSTR D = &A,  E = nullptr, F = &A; 

    int numSet = 0; 
    for (const auto &pointer: {A, B, C, D, E, F}) 
     if (pointer != nullptr) 
      numSet++; 

    std::cout << "Count is " << numSet << std::endl; 
} 

या आप, लैम्ब्डा कार्यों का उपयोग करके आधुनिक सी ++ अपने सभी महिमा में गले लगा सकता है के अनुसार निम्नलिखित:

#include <iostream> 
#include <vector> 

typedef void * LPCWSTR; // Couldn't be bothered including Windows stuff :-) 

int main() { 
    // Only set two for test purposes. 

    LPCWSTR A = nullptr, B = nullptr, C = nullptr; 
    LPCWSTR D = &A,  E = nullptr, F = &A; 

    int numSet = 0; 
    [&numSet](const std::vector<LPCWSTR> &pointers) { 
     for (const auto &pointer: pointers) 
      if (pointer != nullptr) 
       numSet++; 
    } (std::vector<LPCWSTR>{A,B,C,D,E,F}); 

    std::cout << "Count is " << numSet << std::endl; 
} 

कि शायद है हालांकि आपके विशेष मामले के लिए ओवरकिल :-)

+0

धन्यवाद! यह ठीक हो गया। हालांकि, मैं एक्सओआरएस पर भी नजर डालेगा। :-) – Blueeyes789

+0

आवंटन से बचने के लिए 'std :: vector' की बजाय' std :: startizer_list' का उपयोग नहीं कर सका। वह और ... 'std :: count'। –

+4

मैंने पहले कभी सी ++ में तुरंत-लागू लैम्ब्डा अभिव्यक्ति नहीं देखी है ... क्यों न केवल '(ऑटो, पॉइंटर: {ए, बी, सी, डी, ई, एफ}) {... '? –

7

यहाँ एक सरल तरीका है। अगर अंत में 1 के रूप में गिनती आती है, तो अपनी बात करें।

11

std के साथ, आप कर सकते हैं:

const auto vars = {A, B, C}; // Create initializer list. 
const bool onlyOneNotNull = 
    (std::count(vars.begin(), vars.end(), nullptr) == (vars.size() - 1); 
// then you may use find_if to retrieve the non null variable. 
4

सी ++ में, सी के साथ पिछड़े संगतता के लिए, एक संबंधपरक ऑपरेटर का वापसी मूल्य int0 या 1 के बराबर है। तो अगर आप कर सकते हैं:

if ((a != nullptr) + (b != nullptr) + (c != nullptr) == 1) 

आप तार्किक ऑपरेटरों के रूप में ही तार्किक ऑपरेटरों उपयोग करना चाहते हैं, वहाँ भी वियोगी सामान्य रूप और संयोजक सामान्य रूप, यद्यपि अधिक कार्यों के साथ कर रहे हैं।

if ((a && !b && !c) || (!a && b && !c) || (!a && !b && c)) 

 

if ((a || b || c) && (!a || !b) && (!a || !c) && (!b || !c)) 

पूर्व अन्य समाधान के सबसे की तुलना में, इस सरल मामले में पढ़ने के लिए, हालांकि यह जल्दी से भी वर्बोज़ अगर वहाँ थे और अधिक संभव समाधान मिलेगा मुश्किल नहीं है।

आप उन्हें किसी भी कंटेनर में भी चिपका सकते हैं, जैसे std::array<LPCWSTR, 3>, और std::count(pointers.begin(), pointers.end(), nullptr) (जैसा कि जारोड 42 सुझाव दिया गया है)।

2

मैं सामान्य रूप से निम्नलिखित तकनीकों का उपयोग करने का एक बड़ा प्रशंसक नहीं हूं, लेकिन आप इस तथ्य का उपयोग कर सकते हैं कि किसी भी पॉइंटर ptr के लिए !!ptr एक शून्य सूचक के लिए 0 का मूल्यांकन करता है और 1 गैर-शून्य सूचक के लिए लिखने के लिए

if (!!A + !!B + !!C == 1) { 
    ... 
} 

इसे काम करने के लिए एक घने तरीके के रूप में। यह अनिवार्य रूप से @ डेविडिस्ल के समाधान जैसा ही है लेकिन अधिक कॉम्पैक्ट "परीक्षण अगर शून्य" जांच के साथ।

यह दृष्टिकोण लगभग साथ ही स्वीकार किए गए दृष्टिकोण को स्केल नहीं करता है, और यह पढ़ने के लिए मुश्किल है, लेकिन आपके दर्शकों के आधार पर और कोड पढ़ने वाले कौन यह चाल अच्छी तरह से कर सकता है।

+0

यदि आप कोड गोल्फ थे तो आप जीतेंगे! मुझे नहीं लगता कि मैं वास्तव में इसे इस तरह लिखूंगा, लेकिन यह चालाक है। – Davislor

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