如何使用cout输出枚举元素?



我试图输出我声明的enum元素,但例如,当我输入push_ups时,它输出一个像8621623这样的数字,而不是显示push_ups。我也不知道为什么。我是日本人,如果我的英语不好,我很抱歉。非常感谢。

#include <iostream>
#include <string>
using namespace std;
enum exercise { push_ups, sit_ups, squats, walking, radio_calisthenics };
istream& operator>>(istream& is, exercise& i)
{
int tmp;
if (is >> tmp)
i = static_cast<exercise>(tmp);
return is;
}
int main()
{
exercise a;
cin >> a;
cout << a << endl;
}

我试图输出我声明的enum元素,但例如,当我输入push_ups时,它输出一个数字,如8621623,而不是显示push_ups

operator>>过载中,std::cin接受整数,因此push_ups不是整数,因此std::cin将失败,并且i = static_cast<exercise>(tmp);行将被跳过,使a未初始化,当打印时会导致未定义行为发生。

如果要将字符串映射到各自的枚举值,可以通过使用hashmap(在c++中,该容器称为std::unordered_map)手动将每个字符串映射到相应的枚举值来实现:

#include <unordered_map>
// ...
const unordered_map<string, exercise> exercise_map {
{ "push_ups", push_ups },
{ "sit_ups", sit_ups },
{ "squats", squats },
{ "walking", walking },
{ "radio_calisthenics", radio_calisthenics }
};
istream& operator>>(istream& is, exercise& i) {
std::string tmp;
if (is >> tmp) {
auto const it = exercise_map.find(tmp);
if (it != exercise_map.end())
i = it->second;
}
return is;
}
现在,要从枚举中打印出相应的字符串值,我们必须做相反的操作,即使用值在哈希映射中查找键:
ostream& operator<<(ostream& os, exercise& i) {
auto const it = std::find_if(exercise_map.begin(), exercise_map.end(),
[i](std::pair<std::string, exercise> const& e) {
return e.second == i;
}
);
if (it != exercise_map.end())
os << it->first;
return os;
}

完整的代码应该是这样的:

#include <unordered_map>
#include <algorithm>
#include <utility>
#include <iostream>
#include <string>
using namespace std;
enum exercise { push_ups, sit_ups, squats, walking, radio_calisthenics };
const std::unordered_map<std::string, exercise> exercise_map {
{ "push_ups", push_ups },
{ "sit_ups", sit_ups },
{ "squats", squats },
{ "walking", walking },
{ "radio_calisthenics", radio_calisthenics }
};
istream& operator>>(istream& is, exercise& i) {
std::string tmp;
if (is >> tmp) {
auto const it = exercise_map.find(tmp);
if (it != exercise_map.end())
i = it->second;
}
return is;
}
ostream& operator<<(ostream& os, exercise& i) {
auto const it = std::find_if(exercise_map.begin(), exercise_map.end(),
[i](std::pair<std::string, exercise> const& e) {
return e.second == i;
}
);
if (it != exercise_map.end())
os << it->first;
return os;
}
int main() {
exercise a;
cin >> a;
cout << a << endl;
}

push_ups不是一个有效的整数值,因此您试图在is >> tmp上读取a,因此CC_13仍然未初始化。如果要输入名称,则需要读取string,然后手动将其转换为相应的enum值。输出也是一样。没有适当重载的操作符<<a将被视为一个整数。

这一行:

i = static_cast<exercise>(tmp);

当TMP保存一个介于0和4之间的int值时将完美地工作,

但是在你的情况下,tmp = push_ups打破了强制转换操作,你的refi初始化错误

您似乎在理解enums方面有问题。
我认为您输入了字符串值"push_up ">
enum只是一个整数类型的占位符,主要用于增加程序的可读性。

认为enum是表达

之类内容的更好方式。
// chess_piece = 1 : pawn
// chess_piece = 2 : rook
// chess_piece = 3 : bishop
...
int chess_piece;

enum ChessPiece { Pawn, Rook, Bishop, ...};
ChessPiece chess_piece;

在上面的变体中,很明显pawn、rook等名字都是注释enum在这方面没有什么不同。写if(chess_piece == Pawn)显然更容易读,但是"典当"这个词只是编程语言中的一部分代码,不在编译程序中

你能做的是添加一些像

exercise exercise_from_string(const std::string& input)
{
if(input == "push_ups") return push_ups;
...

对于开关也是如此。我还建议你有一个"未知"的值。如果这样的函数找不到已知项。

编辑:当我写这篇文章的时候,另一个人更新了他的答案,他使用std::map的代码比我的好。
希望我的回答能帮助你理解核心问题。

最新更新