我试图重载>>运算符读取单个(使用enum Symbol {e,a,b,c,d};
创建)符号:
istream & operator >> (istream & is, Symbol & sym) {
Symbol Arr[]={e,a,b,c,d};
char ch;
is>>ch;
if (strchr("eabcd",ch))
sym=Arr[ch-'e'];
else {
is.unget();
is.setstate(ios::failbit);
}
return is;
}
但这会读取一些垃圾(数字)而不是我想要的东西,当我尝试使用我的<<<<<<<<<<<<<超负荷,我做错了什么?
编辑:哦,当然我在开始时添加了using namespace std;
,与包含iostream
和cstring
相同。
答案 0 :(得分:1)
这里有一些问题。首先,让我们来修复你的支撑。只需要总是使用大括号。很难看出它们的内容是什么:
istream & operator >> (istream & is, Symbol & sym) {
Symbol Arr[]={e,a,b,c,d};
char ch;
is>>ch;
if (strchr("eabcd",ch)) {
sym=Arr[ch-'e'];
}
else {
is.unget();
is.setstate(ios::failbit);
}
return is;
}
好的。现在,如果用户输入'a'
之类的内容会发生什么。 strchr
成功,然后您sym = Arr[ch - 'e']
。但在这种情况下,ch - 'e'
为-4
。那个地方有一些完全随机的内存,所以你得到了垃圾。要实际使用strchr
,您需要执行以下操作:
const char* options = "eabcd";
if (const char* p = strchr(options, ch)) {
sym = Arr[p - options];
}
但那太糟糕了。我建议只使用一个开关:
switch (ch) {
case 'e': sym = e; break;
case 'a': sym = a; break;
...
default:
is.unget();
is.setstate(ios::failbit);
}
,is >> ch
可能会失败,您也不会检查。你应该:
istream& operator>>(istream& is, Symbol& sym) {
char ch;
if (is >> ch) {
switch(ch) { ... }
}
return is;
}
答案 1 :(得分:0)
如果ch
为'a'
,ch - 'e'
(97 - 101)将为负数(-4),这将导致访问数组Arr
界限。这导致了未定义的行为。
您拥有符号的方式,您需要使用switch
声明:
switch (ch)
{
case 'a':
sym = a;
break;
case 'b':
sym = b;
break;
case 'c':
sym = c;
break;
case 'd':
sym = d;
break;
case 'e':
sym = e;
break;
default:
// Nothing to do
break;
}
如果您想使用Arr
,则需要将Arr
定义为:
Symbol Arr[]={a,b,c,d,e};
然后,您可以按如下方式访问数组,并避免使用switch
语句:
sym=Arr[ch-'a']; // ch - 'a' is 0 when ch is 'a'
// ch - 'a' is 4 when ch is 'e'.