Использование strchr для перегрузки & gt; & gt;

Я пытаюсь перегрузить оператор >> для чтения одного (создан с 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

Решение

Здесь несколько вещей не так. Во-первых, давайте исправим ваше крепление. Просто всегда используйте брекеты. Очень трудно понять, что и с чем связано:

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

Другие решения

Если 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'.
0

По вопросам рекламы [email protected]