繁体   English   中英

scanf()与C ++枚举

[英]scanf() with C++ enums

以下是我们的代码库中的典型情况。

enum ConfigOption { CONFIG_1=1, CONFIG_2=2, CONFIG_3=3 }

ConfigOption cfg1, cfg2;

sscanf(s, "%d", &cfg1);

这是一个内部使用的仿真软件。 没有分发。 易于维护和正确性非常重要。 可移植性和用户界面 - 不是真的。

问题是c ++中的enum不一定是int 因此,我们会收到编译器警告,并且在使用其他编译器或启用优化时可能会出现错误行为。

一种解决方案就是将&cfgint* 但是,这不会捕获编译器决定在enum分配int以外的东西的情况。

所以我提出了以下解决方案:

template<typename T> inline
int& eint(T& enum_var) {
    assert(sizeof(T) == sizeof(int));
    return (int&)enum_var;
}

现在使用scanf如下:

sscanf(s, "%d", &eint(cfg1));

我很想听听上述问题的意见和其他(更好的)解决方案。 请记住,其中一个目标是保持代码简单。 这不是“生产质量”的东西,你添加的越多 - 维护就越困难。

如果你有像vs2010这样的现代编译器,你可以指定枚举元素的大小

enum class ConfigOption: unsigned int {CONFIG_1=1, CONFIG_2=2, CONFIG_3=3};

它在C ++ 0x中的新功能

我的解决方案是将枚举强制到最小尺寸。这就是微软在他们的DirectX头文件中为他们的枚举所做的事情(我不得不承认这是一个很好的技巧)。

他们通过添加如下虚拟枚举来强制枚举的大小等于int:

typedef enum 
{
  fooo = 1,
  baar = 2,
  ___Force32Bit = ~0UL
} MyEnum;

现在枚举总是至少是int的大小。

如果你愿意,你可以把它放在顶部..这个强迫enum的大小很长:

typedef enum 
{
  fooo = 1,
  baar = 2,
  ___Force64Bit = ~0ULL
} MyEnum;

我知道,这不是一个超级干净的解决方案。 我认为这样的解决方案不存在,并且到目前为止,强制执行最小尺寸对我来说效果很好。 如果你从32位到64位代码,你可能需要调整代码,但通常在这些情况下你必须检查代码的某些部分,所以没有大问题。

顺便说一句 - 对不起C代码,我知道这个问题被标记为C ++,但我是C-guys :-)

为什么不把它作为一个实际的int读取?

enum ConfigOption { CONFIG_1=1, CONFIG_2=2, CONFIG_3=3 };
ConfigOption cfg1;

int i;
sscanf(s, "%d", &i);
cfg1 = i;

这样你就可以进行更全面的有效性检查(例如测试读取整数是否在你的enum类型范围内)。

(当然,如果您一直担心检测错误,对于这样的简单解析,您应该使用strtolstrtoul而不是sscanf 。)

您可以尝试使用boost::lexical_cast ,或者如果您不使用boost并且不想在这种情况下开始使用它,您可以自己编写一个简化版本。 举个例子来看看这个SO答案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM