simanのブログ

ゆるふわプログラマー。競技プログラミングやってます。Ruby好き

topcoderにおけるC++の標準入力読み込み

競技プログラミングをやっていると標準入力から1行ずつ読み込んで処理をする場合が
出てくる。要素の数が決まっている場合はcinで対応出来るが、そうでない場合が多い。


例(要素の数が決まっている場合)

#include <iostream>

using namespace std;

int main(){
  int n, m;
  cin >> n >> m;

  cout << "first elem is " << n << " second elem is " << m << endl;
  return 0;
}
3 1
first elem is 3 second elem is 1

要素の数が決まってない場合でよくあるのは格子状の問題が多い。たとえば迷路
を解く問題があったとして、「最初の1行目が迷路のサイズを表す」なんてよくある。
そして2行目以降からデータの入力が始まる場合。

#include <iostream>
#include <string>

using namespace std;

int main(){
  int height, width;
  string line;

  cin >> width >> height;

  char maze[height][width];

  for(int i=0; i<height; i++){
    getline(cin, line);
    for(int j=0; j<width; j++){
      maze[i][j] = line[j];
    }
  }

  for(int i=0; i<height; i++){
    for(int j=0; j<width; j++){
      cout << maze[i][j];
    }
    cout << endl;
  }
  return 0;
}
3 3
..S
##.

..S
##.


なんと迷路の3行目のデータを読み込んでくれていない。これは最初のcinの操作で改行文字'\n'だけが残ってしまったからである。なので最初のgetline(cin, line)では改行文字だけを読み込んでしまっているのである。


これを回避するには最初のcinの後にcin.ignore()で1文字無視してあげればよい。

cin >> width >> height; cin.ignore();
3 3
..S
##.
G..
..S
##.
G..

これで大丈夫。

参考URL
「プログラミングのテクニック/入力の処理(C,C++)」
http://wikiwiki.jp/kyopro/?%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%A4%CE%A5%C6%A5%AF%A5%CB%A5%C3%A5%AF%2F%C6%FE%CE%CF%A4%CE%BD%E8%CD%FD%28C%2CC%2B%2B%29