Я пытаюсь перегрузить оператор >> для чтения одного (создан с 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
,
Здесь несколько вещей не так. Во-первых, давайте исправим ваше крепление. Просто всегда используйте брекеты. Очень трудно понять, что и с чем связано:
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;
}
Если 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'.