>>

2016-03-18 11 views
0

私は、単一の(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; 
} 

をしかし、これは代わりに私が何であったかのいくつかのゴミ(番号)を読み込みます探して、私の< <過負荷でそれを印刷しようとするとセグメント違反につながる、私は間違って何ですか? 編集:ああ、もちろん、私はiostreamcstringを含むと同じように、開始時にusing namespace std;を追加しました。

ch
+0

ちょうど興味があります、あなたは解決したい問題はありますか? – Incomputable

+0

これは、大学のObject Programmingコースのための大きなプロジェクトの一部です。記号を読んで追加表などで操作する必要があります。 –

答えて

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です。それはどこかで全く無作為なビットなので、あなたはゴミを手に入れています。

const char* options = "eabcd"; 
if (const char* p = strchr(options, ch)) { 
    sym = Arr[p - options]; 
} 

をしかし、それは一種のひどいです:実際にstrchrを使用するには、のような何かをする必要があると思います。

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; 
} 
+0

しかし、なぜそれが-4で、1でないのですか? 'a'は私のコードで' e'の後に来ますが、 'strchr'の仕組みを誤解していますか? –

+0

@GizmoofArabiaあなたは 'char'sを引いています。あなたのenumは無関係です。 – Barry

+0

@GIzmoofArabia、いいえあなたがsubstructionをやっているとき、あなたはASCIIコードの置換を行っているので、 'a' - 'e'は負です。 [ASCIIコード](http://www.asciitable.com/)をご覧ください。 decとcharの列を見てください。 – Incomputable

0

'a'ch - 'e'(97から101)である場合には、範囲外の配列Arrアクセスにつながる負の数(-4)、あろう。それは未定義の動作につながります。

あなたのシンボルを持っている方法は、あなたがswitchステートメントを使用する必要があります:

Symbol Arr[]={a,b,c,d,e}; 

:あなたはArrを使用したい場合は

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を定義する必要があります次に、配列にアクセスしてswitchの文を避けることができます。

sym=Arr[ch-'a']; // ch - 'a' is 0 when ch is 'a' 
        // ch - 'a' is 4 when ch is 'e'. 
+0

'e ' - ch'は' 「e」から「a」までの順番ではない。 –

+0

@RemyLebeau、エラーを指摘してくれてありがとう。今修正されました。 –

関連する問題