从 cin 中为 c++ 中的结构中的多个枚举获取输入
Getting input from cin for several enums within a struct in c++
以下是我的代码:
enum Color {red, blue};
enum Number {3,4};
enum Shape {circle, square};
struct article
{
enum Color color;
enum Number number;
enum Shape shape;
} article_1;
//assume I have the below for all three enums
std::istream& operator>>( std::istream& is, Color& I )
{
int tmp ;
if ( is >> tmp )
i = static_cast<Color>( tmp ) ;
return is ;
}
int main ()
{
cout<<"Enter the Color : ";
cin>>article_1.color;
cout<<"Enter the Number : ";
cin>>article_1.number;
cout<<"Enter the Shape : ";
cin>>article_1.shape;
return 0;
}
代码编译没有任何错误。但是,当终端弹出要求我输入颜色时,当我输入红色时,终端消失了,我收到一条错误消息 Program.exe has exited with code 0(0x0)
。我做错了什么?
enums 是 编译级 功能。应用程序编译后,只有数字。您放入枚举中的字符串在程序 运行.
时被数字替换
您必须 cin 一个字符串并将其与 运行time 字符串(不是枚举)进行比较以获得您需要的内容。
std::string x;
cin >> x;
if (x == "red")
{
}
您还可以创建 std::map<std::string,int>
。 scohe001 的 comment 也展示了一些方法。
C++ 中没有字符串和枚举之间的智能转换。
您的输入代码无效,因为您从输入流中读取了 int
并将其转换为颜色:
- 如果您输入一个与枚举值编码之一对应的有效整数,它可能会起作用。
- 但是如果输入字符串,会因为类型不兼容导致输入操作失败。输入流出错,在您清除错误标志之前,对该流的所有后续操作都将失败。
如果你想读取一个字符串,你需要照顾它。例如使用以下代码:
std::istream& operator>>( std::istream& is, Color& I )
{
std::string tmp;
if ( is >> tmp ) {
for (auto&c:tmp)
c=std::tolower(c);
if (tmp=="red") I = red;
else if (tmp=="blue") I = blue;
// but what happens if the string is invalid ???
}
return is ;
}
std::ostream& operator<<( std::ostream& os, Color& O )
{
std::string tmp;
switch (O) {
case red: tmp="red"; break;
case blue: tmp="blue"; break;
default: tmp="oops!!";
}
return os<<tmp ;
}
当然,这只是一个幼稚的例子。实际上,您可能有一个 std::map 来保存字符串和枚举之间的关联,反之亦然。
值得了解:
枚举中的枚举数可以映射为整数值。默认情况下,第一个枚举器 (red
) 映射到 0。随后的枚举器获得的值比前面的枚举器多 1(即 blue
为 1)。
但您可以自由设置一个值(例如 enum Color { red=2, green, blue=green+4 };
)。这就是为什么在 int 和 enum 之间转换是合法的。但这样做时要非常小心,因为一旦整数与枚举值不完全匹配,它就会变得复杂。
以下是我的代码:
enum Color {red, blue};
enum Number {3,4};
enum Shape {circle, square};
struct article
{
enum Color color;
enum Number number;
enum Shape shape;
} article_1;
//assume I have the below for all three enums
std::istream& operator>>( std::istream& is, Color& I )
{
int tmp ;
if ( is >> tmp )
i = static_cast<Color>( tmp ) ;
return is ;
}
int main ()
{
cout<<"Enter the Color : ";
cin>>article_1.color;
cout<<"Enter the Number : ";
cin>>article_1.number;
cout<<"Enter the Shape : ";
cin>>article_1.shape;
return 0;
}
代码编译没有任何错误。但是,当终端弹出要求我输入颜色时,当我输入红色时,终端消失了,我收到一条错误消息 Program.exe has exited with code 0(0x0)
。我做错了什么?
enums 是 编译级 功能。应用程序编译后,只有数字。您放入枚举中的字符串在程序 运行.
时被数字替换您必须 cin 一个字符串并将其与 运行time 字符串(不是枚举)进行比较以获得您需要的内容。
std::string x;
cin >> x;
if (x == "red")
{
}
您还可以创建 std::map<std::string,int>
。 scohe001 的 comment 也展示了一些方法。
C++ 中没有字符串和枚举之间的智能转换。
您的输入代码无效,因为您从输入流中读取了 int
并将其转换为颜色:
- 如果您输入一个与枚举值编码之一对应的有效整数,它可能会起作用。
- 但是如果输入字符串,会因为类型不兼容导致输入操作失败。输入流出错,在您清除错误标志之前,对该流的所有后续操作都将失败。
如果你想读取一个字符串,你需要照顾它。例如使用以下代码:
std::istream& operator>>( std::istream& is, Color& I )
{
std::string tmp;
if ( is >> tmp ) {
for (auto&c:tmp)
c=std::tolower(c);
if (tmp=="red") I = red;
else if (tmp=="blue") I = blue;
// but what happens if the string is invalid ???
}
return is ;
}
std::ostream& operator<<( std::ostream& os, Color& O )
{
std::string tmp;
switch (O) {
case red: tmp="red"; break;
case blue: tmp="blue"; break;
default: tmp="oops!!";
}
return os<<tmp ;
}
当然,这只是一个幼稚的例子。实际上,您可能有一个 std::map 来保存字符串和枚举之间的关联,反之亦然。
值得了解:
枚举中的枚举数可以映射为整数值。默认情况下,第一个枚举器 (red
) 映射到 0。随后的枚举器获得的值比前面的枚举器多 1(即 blue
为 1)。
但您可以自由设置一个值(例如 enum Color { red=2, green, blue=green+4 };
)。这就是为什么在 int 和 enum 之间转换是合法的。但这样做时要非常小心,因为一旦整数与枚举值不完全匹配,它就会变得复杂。