我试图输出我声明的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初始化错误
您似乎在理解enum
s方面有问题。
我认为您输入了字符串值"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
的代码比我的好。希望我的回答能帮助你理解核心问题。