我有一个文件,其值如:START和STOP。我还声明了以下枚举:
enum Type {
START,
STOP
};
我正在尝试将枚举设置为等于文件中的第一个值,如下所示:
enum Type foo;
ifstream ifile;
ifile.open("input.txt");
ifile >> foo;
我收到错误:'ifile>>中的'运营商>>'不匹配富”。
我该如何正确地做到这一点?
答案 0 :(得分:5)
最快的方法是读入一个int并将其强制转换为Type枚举。
答案 1 :(得分:1)
对于用户定义的类型,不会重载流插入运算符。您可以为类型为enum
的{{1}}对象定义一个,也可以使用其中一个现有重载来阅读Type
或unsigned char
,然后将值更改为{{1} }}
答案 2 :(得分:1)
http://condensedcpp.com/Enums.html
std::istream& operator >> (std::istream& i, Season& season)
{
season = SPRING;
std::string value;
if (i >> value) {
if (value == "Summer") {
season = SUMMER;
}
else if (value == "Autumn") {
season = AUTUMN;
}
else if (value == "Winter") {
season = WINTER;
}
}
return i;
}
答案 3 :(得分:1)
我发现在我的特定情况下,以下代码是最佳解决方案:
template <class T> T a2e(string c, const string a[], const int size) {
for (int i=0; i < size; i++) {
if (c == a[i]) {
return static_cast<T>(i);
}
}
}
将使用如下:
enum StateType {START, STOP};
const int MAXVALUES = STOP+1;
const string stateNames[MAXVALUES] = {"START", "STOP"};
enum StateType state;
ifstream ifile;
ifile.open("input.txt");
ifile >> foo;
state = a2e <enum StateType> (foo, stateNames, MAXVALUES);
希望这可以帮助将来的某个人。感谢所有就如何解决这个问题提出建议的人。
答案 4 :(得分:1)
我认为这将是对blcArmadillo的模板的答案和导航器的输出回答的改善。在文件AToE.h中:
#ifndef AToE_h
#define AToE_h
#include <string>
#include <stdexcept>
#include <cctype>
template <class T, char* A, int size, char* enumName> class AToE
{
std::string S[size]; // to hold A as std::string
T t;
bool valid; // whether t holds a valid value
public:
AToE()
{
initialize();
valid = false;
};
AToE(T& t) : t(t)
{
initialize();
valid = true;
};
AToE(std::string const& s)
{
initialize();
valid = true;
t = toEnum(s); // this has to be done after initialize()
};
void initialize()
{
int i = 0, j = 0;
while (i < size)
{
while (A[j] != ',')
{
if (not isspace(A[j]))
{
S[i] += A[j];
}
++j;
}
++j; // to count skipped comma
++i;
}
};
T get()
{
if (valid) return t;
std::string e = "ERROR - IO object is not initialized to a valid ";
e += enumName;
throw std::runtime_error(e);
};
friend std::ostream& operator<<(std::ostream& os, AToE& a)
{
if (a.valid) return os << a.S[a.t];
std::string e = "OUTPUT ERROR - IO object is not initialized to a valid ";
e += enumName;
throw std::runtime_error(e);
};
T toEnum(std::string const& s)
{
for (int i=0; i<size; ++i)
{
if (s == S[i])
{
valid = true;
t = static_cast<T>(i);
return t;
}
}
std::string e = "CONVERSION ERROR - " + s + " is not a valid " + enumName;
throw std::out_of_range(e);
}
std::string toString();
{
if (valid) return S[t];
std::string e = "CONVERSION ERROR - IO object is not initialized to a valid ";
e += enumName;
throw std::runtime_error(e);
}
friend std::istream& operator>>(std::istream& is, AToE& a)
{
std::istream::sentry isSentry(is); // sentry for is
if (not isSentry) return is; // stream error
std::string s;
if (is >> s) a.t = a.toEnum(s);
return is;
}
};
#endif
然后可以在StateType.h中这样使用:
#ifndef StateType_h
#define StateType_h
#include "AToE.h"
enum StateType {START, STOP, NUMBER_OF_STATE_TYPES};
char STATE_TYPE_NAMES[] = "START, STOP,"; // last comma is necessary
char STATE_TYPE_NAME = "StateType";
typedef AToE <StateType, STATE_TYPE_NAMES, NUMBER_OF_STATE_TYPES, STATE_TYPE_NAME> StateTypeIO_T;
#endif
和主要内容:
#include <cstdio>
#include <fstream>
#include <iostream>
#include "StateType.h"
int main()
{
std::ifstream infile;
infile.open("input.txt");
StateTypeIO_T stateIO; // uses AToE() constructor
//StateType t = stateIO.get(); // uncomment to test get fail condition
//std::cout << stateIO<< std::endl; // uncomment to test << fail condition
while (infile >> stateIO) // uses AToE >> operator
{
std::cout << stateIO<< std::endl; // uses AToE << operator
StateType s = stateIO.get(); // uses AToE get method
StateTypeIO_T stateOut(s); // uses AToE(T& t) constructor
std::cout << stateOut << endl;
}
// remove DOG from input.txt in order for the program to run past here
std::string stateString = "STOP";
std::cout << stateString << std::endl; // prints STOP
StateTypeIO_T stateIO2(stateString); // uses AToE(std::string const& s) constructor
std::cout << stateIO2 << std::endl; // prints STOP
printf("state = %s\n", stateIO2.toString().c_str()); // prints state = STOP
stateString = "START";
stateIO2.toEnum(stateString); // sets stateIO2.t to START
std::cout << stateIO2 << std::endl; // prints START
StateTypeIO_T stateIO3();
//std::cout << stateIO3.toString() << std::endl; // uncomment to test toString fail condition
StateType s2;
//s2 = stateIO3.toEnum("CAT"); // uncomment to test toEnum fail condition
s2 = stateIO3.toEnum("STOP");
std::cout << stateIO3 << std::endl; // prints STOP
StateTypeIO_T stateOut2(s2);
std::cout << stateOut2 << std::endl; // prints STOP
};
其可与一个input.txt的文件可以使用-
START
STOP
STOP
START
DOG
这将打印出的每个条目两次,直到它碰到上DOG发生输入错误,并且如果从input.txt中除去DOG,将打印出的每个条目两次,接着 -
STOP
STOP
state = STOP
START
STOP
STOP
答案 5 :(得分:0)
@popester
我会将此作为回复发布,但过去的经验代码在SO的回复中并不能很好地转换。
我刚刚编写了以下简短程序来测试你的建议:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
enum Type {
START,
STOP
};
int bar;
enum Type foo;
ifstream ifile;
ifile.open("input.txt");
ifile >> bar;
foo = (Type) bar;
cout << "bar: " << bar << endl;
cout << "foo: " << foo << endl;
}
以下是我的input.txt文件:
STOP
我编译并运行程序并输出以下内容:
bar:-1207974988
foo:-1207974988
我只是误解了你的建议吗?如果你能引导我朝着正确的方向前进,那就太棒了。谢谢你的帮助。