C言語データ入力メモ2
またもやscanf系の入力でハマったのでメモ。
問題:
ステップ1.整数の入力を1つ、scanfで受け取る
ステップ2.ステップ1で受け取った整数が0ならば終了、0以外ならば文字列をgetsで受け取ってputsで出力し、ステップ1に戻る
例えば、次のコードは正しく動作するだろうか?
#include <cstdio> #include <algorithm> const int MAX_BUFSIZE(128); int main(){ int n; while(true) { scanf("%d", &n); if(n == 0) break; else { char buf[MAX_BUFSIZE]; std::fill(buf, buf + MAX_BUFSIZE, 0); gets(buf); puts(buf); } } }
答えはNoである。
getsで新しい文字列を標準入力から受け取るつもりが、scanfで受け取ってない分のストリームが残っていて、こっちを先に受け取ってしまう。
次に、scanfの部分で%dの直後に空白を入れたコードを考える。
#include <cstdio> #include <algorithm> const int MAX_BUFSIZE(128); int main(){ int n; while(true) { scanf("%d ", &n); //%dの次に空白 if(n == 0) break; else { char buf[MAX_BUFSIZE]; std::fill(buf, buf + MAX_BUFSIZE, 0); gets(buf); puts(buf); } } }
これによって、整数を入力した後の改行が区切れとみなされて、正常にgetsが受け付けられるようになる。ただ、この変更後の問題は、整数として0を入力した時で、何故か思い通りに動かない。この理由はいまだにわからないので詳しい方教えてください。。。
結局、思い通りに動くとわかったのは次のコード
#include <cstdio> #include <algorithm> const int MAX_BUFSIZE(128); int main(){ int n; while(true) { scanf("%d", &n); getchar(); //getcharで改行を受け取る if(n == 0) break; else { char buf[MAX_BUFSIZE]; std::fill(buf, buf + MAX_BUFSIZE, 0); gets(buf); puts(buf); } } }
ちなみにこの入力フォーマットは競技プログラミングでよく出くる。なので、これが出来ないとスタート地点にも立ててないということになる。ぐぬぬ。
その他、C++は標準でsplitが使えないのでstringstrem+STLコンテナで疑似splitやる必要があったり何かと大変である。
C言語入門 (ASCII SOFTWARE SCIENCE Language)
- 作者: レスハンコック,サバゼミール,モーリスクリーガー,Les Hancock,Saba Zamir,Morris Krieger,倉骨彰,三浦明美
- 出版社/メーカー: アスキー
- 発売日: 1992/09
- メディア: 単行本
- 購入: 3人 クリック: 34回
- この商品を含むブログ (13件) を見る