这段代码给了我错误:
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*
类型上切换案例或等效案例?
答案 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;
}