6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[短文メモ][初級記事]std::cinから整数受け取るのは、エラーチェックしないと怖くて使えないね

Posted at

CodeIQさんの問題に、いつもPython使ってるのでたまにはC++を、と思ったらハマったのだけど。
原因がようやく分かった。std::cinでの読み込みが失敗していた。失敗しても例外とか投げずに静かに失敗するので、分からないんですね。

例:整数のみからなるテキストがstdinに渡される、としよう。行数は、前もって分からない。
これをvectorに読み込みたい。

よくない例
#include <iostream>
#include <vector>

int main(){
    int t;
    std::vector<int> v;

    while(!std::cin.eof()){
        std::cin >> t;
        v.push_back(t);
    }
    for(auto it=v.begin();it!=v.end();++it){
        std::cout << *it << std::endl;
    }
}

普通に、このように書いて、以下のように入力したら。

stdinにこれを入力
1
2
3

こうなった。

実行結果
1
2
3
3

原因は、空行を整数として解釈しようとして、できなかったので、tを何も変更しなかったことと思われる。

改善
int main(){
    int t;
    std::vector<int> v;

    while(!std::cin.eof()){
        std::cin >> t;
        if(std::cin.fail()) break;  // エラーチェックを付け加えた
        v.push_back(t);
    }
    for(auto it=v.begin();it!=v.end();++it){
        std::cout << *it << std::endl;
    }
}

こうしたら、3がダブらずに済む。
せっかくwhileの中にループ抜ける条件書いてるのに・・・・

ちなみに、整数ではなく間違えて文字を入力してしまったときは、tには0が入力され、また、
std::cin.clear()でエラーをクリアし、std::cin.ignore()で読み捨てないといけないみたい。

お手軽にできるのかと思いきや、結構めんどくさいのですね。

6
1
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?