在char *上切换案例

时间:2014-12-17 23:13:32

标签: c++ string char switch-statement

这段代码给了我错误:

const char* name = pAttr->Name(); // attribute name
const char* value = pAttr->Value(); // attribute value

switch(name) // here is where error happens: must have integral or enum type
{
case 'SRAD':    // distance from focal point to iso center
    double D = atof(value);
    break;
case 'DRAD':    // distance from iso center to detector
    break;
default:
    break;
}

switch(name)是发生错误的地方。它说它是一个整体或枚举类型。那么我如何在char*类型上切换案例或等效案例?

5 个答案:

答案 0 :(得分:11)

你不能在这里使用switch;如错误所示,不支持const char*。这也是一件好事,因为通过指针比较两个C字符串只比较指针,而不是它们指向的字符串(考虑"hello" == "world")。

即使它是,你也试图将你的C字符串与多字符文字进行比较,这肯定不是你想要的,尤其是因为它们的类型{{1和实现定义的值;我想你的意思是写int,而不是"SRAD"

由于你正在使用C ++,你应该这样做:

'SRAD'

(我还修正了const std::string name = pAttr->Name(); const std::string value = pAttr->Value(); if (name == "SRAD") { double D = atof(value.c_str()); // use std::stod(value) in C++11 // ... } else if (name == "DRAD") { // ... } else { // ... } 初始化中name的使用情况; Remy是对的 - 你必须在D这里value,因为"SRAD"不可能被解释为double。)

答案 1 :(得分:3)

另一种选择是使用本地map来存储与字符串值对应的整数值,从字符串中获取整数值,然后在积分值上使用switch

enum { SRAD = 1, DRAD, ... };

static std::map<std::string, int> localMap;
// Fill up the map.
if ( localMap.empty() )
{
   localMap["SRAD"] = SRAD;
   localMap["DRAD"] = DRAD;
}

const char* name = pAttr->Name(); // attribute name
const char* value = pAttr->Value(); // attribute value

int val = localMap[name];

switch (val)
{
    case SRAD:    // distance from focal point to iso center
    {
        double D = atof(value);
        break;
    }

    case DRAD:    // distance from iso center to detector
        break;

    default:      // name is unknown
        break;
}

答案 2 :(得分:1)

好的,这是完全,完全是EVIL ,但我已经完成了,它确实有效:

// Must be a #define because an inline func won't give you a constant
#define MAKECODE(p) ((((p)[0])*0x01000000) \
                   + (((p)[1])*0x00010000) \
                   + (((p)[2])*0x00000100) \
                   +  ((p)[3]) )
// Note: I did not verify that the parenthesis matched. 

switch(MAKECODE(name))
{
  case MAKECODE("SRAD"):    // distance from focal point to iso center
     double D = atof(name);
     break;
  case MAKECODE("DRAD"):    // distance from iso center to detector
     break;
  default:
     break;
}

注意:如果字符串name指向的字符串少于4个字符,则会发生 BAD 事情。 case语句中的字符串少于4个字符(但可能只是编译器错误)会发生不同的坏事。

答案 3 :(得分:0)

switch语句只能计算整数或枚举类型的表达式(或可转换为此类型),并且每个case标签中的表达式必须是常量表达式。

'SRAD'不是字符串文字。它是一个字符文字,具有类型int的实现定义值。 (这是一个几乎无用的语言功能,我已经看到错误地使用了它,而不是我看到它使用得当。)

如果你想使用C风格的语言功能,避免像C ++ std::string之类的东西,那么等效的是if / else链:< / p>

if (strcmp(name, "SRAD") == 0) {
    // ...
}
else if (strcmp(name, "DRAD") == 0) {
    // ...
}
else {
    // ...
}

如果您使用std::string(这是可取的),代码将类似,但您可以使用==而不是strcmp

您可以设置一个数据结构,让我们计算一个离散值,然后您可以在switch / case语句中使用R Sahu's answer建议。这将节省可能进行N字符串比较的开销。在我看来,对于像这样的简单案例来说,这将是过度的。如果您的实际代码更大且更复杂,则值得考虑。

或者您可以考虑重新设计数据结构,以便直接存储和测试枚举值,然后通过查找表从该枚举值中获取字符串值。

答案 4 :(得分:0)

这个答案主要是为了好玩,但如果保证name字符串总是长达4个字节,它就会起作用。

#include <iostream>

using namespace std;

// precondition: name is exactly 4 chars in length
uint32_t convert(const char* name)
{
    uint32_t val = uint32_t(name[3])
    + (uint32_t(name[2]) << 8)
    + (uint32_t(name[1]) << 16)
    + (uint32_t(name[0]) << 24);
    return val;
}

int main()
{
    const char* name = "SRAD"; // attribute name
    const char* value = "10"; // attribute value


    switch(convert(name)) // convert the string value to integral type uint32_t
    {
        case 'SRAD':    // use arcane knowledge of C to construct an int32 representation of ascii digits
        {
            double D = atof(value);
            cout << "SRAD " << D << endl;
            break;
        }
        case 'DRAD':    // distance from iso center to detector
            cout << "some operation on value here " << endl;
            break;

        default:
            break;
    }

    return 0;
}