AtCoder Beginner Contest 191のC - Digital GraffitiをC言語で解いたときのはなし。
例として以下の入力が与えられていた。
5 5 ..... .###. .###. .###. .....
これを以下のコードで読み込もうとすると、最終行(.....の部分)を読み込むことができなかった。
int h, w, i, j; char s[10][10]; scanf("%d %d", &h, &w); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { scanf("%c", &s[i][j]); printf("%c", s[i][j]); } }
//読み込み結果 ..... .###. .###. .###.
これはscanfでchar型変数を読み込む際、改行も1文字として読み込んでしまうことが原因である(上の読み込み結果を反転表示してもらえば、改行が読み込まれていることがわかるだろう)。
さらに次にscanfを使う場合に備えて,残った改行は%*cで読み飛ばします。これで保持されていた入力データはすべて処理されたことになります。但し,次に読み取るものが%dなど数値である場合には,これをしなくても特に影響はありません。
(標準入力から安全に文字列を受け取る方法いろいろ - Qiitaより引用)
この解説に従い、以下のようにコードを書き換えると、改行を無視して読み込むことができた。
int h, w, i, j; char s[10][10]; scanf("%d %d%*c", &h, &w); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { scanf("%c", &s[i][j]); printf("%c", s[i][j]); } scanf("%*c"); }
/* 読み込み結果 */ ......###..###..###......