检查C ++中是否只有一个字符串变量不是nullptr

时间:2017-08-04 04:18:01

标签: c++ variables null nullptr

我有三个LPCWSTR字符串变量,名为ABC

我从另一个函数中分配它们,如果出现问题,有时会返回nullptr。像这样:

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

现在,对于那些带有这些变量的东西,我需要检查这些变量中是否只有一个不是nullptr(只分配了一个变量)。

我试着这样做:

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

欢迎任何关于如何做到这一点的想法。

5 个答案:

答案 0 :(得分: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

下一步将使用基于范围的for循环以及支撑的初始化列表,按照以下完整程序:

#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;
}

或者你可以通过使用lambda函数来接受现代C ++,如下所示:

#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;
}

然而,对于你的特定情况,这可能有点过分了: - )

答案 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.

答案 2 :(得分:7)

这是一个简单的方法:

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

检查每个是nullptr并增加计数(如果不是)。如果计数到最后为1,那么就做吧。

答案 3 :(得分:4)

在C ++中,为了与C向后兼容,关系运算符的返回值是int等于01。所以你可以这样做:

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)(如Jarod42建议的那样)。

答案 4 :(得分:2)

我不是很喜欢使用类似下面的技术,但是你可以使用这样的事实:对于空指针,ptr求值为0的任何指针!!ptr和1为写入

的非空指针
if (!!A + !!B + !!C == 1) {
    ...
}

作为一种密集的方式来实现这一点。它与@ Davislor的解决方案基本相同,但是使用更紧凑的“测试如果为空”检查。

这种方法的扩展程度几乎与接受的方法不同,并且阅读起来比较棘手,但根据您的受众和谁在阅读代码,它可以很好地完成这一操作。