みけCATのにっき(仮)
つれづれなるまゝに、日くらし、PCにむかひて、心に移りゆくよしなし事を、そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。
(本当か!?)
出典

C言語の入力 is 難しい

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

C言語の入力 is 難しい

投稿記事 by みけCAT » 10年前

大学生活2年目になり、プログラミングの授業が始まりました!
与えられた仕様を満たすプログラムを書くだけの簡単なお仕事です!

例えば、「整数を読み取り、符号を反転した整数を出力する」という課題。
もしオンラインジャッジに投げるなら、これだけの簡単なプログラムですね。

CODE:

#include 

int main(void) {
	int a;
	scanf("%d",&a);
	printf("%d\n",-a);
	return 0;
}
しかし、今回の授業では人力で採点されます。したがって、きちんと入力のチェックをするべきでしょう。
というわけで、このコードを提出しました。

CODE:

#include 

int main(void) {
  int input;         /* 入力された整数 */
  int answer;        /* 符号を反転した整数 */
  int wantInput = 1; /* 入力が必要であるというフラグ */
  while(wantInput) {
    printf("Input an integer : ");
    if(scanf("%d",&input) == 1) {
      /* 整数を読み込めたら、これ以上の入力は必要ない */
      wantInput = 0;
    } else {
      /* 整数の読み込みに失敗したので、不要な入力を掃除する */
      char readChar = '\0';
      /* 改行が読み込まれるまで入力を読み込む */
      while(readChar != '\n') {
        if(scanf("%c",&readChar) != 1) {
          /* それでも読み込みに失敗したら終了する */
          return 1;
        }
      }
    }
  }
  /* 0から入力された整数を引くことで、入力の符号を反転した整数を得る */
  answer = 0 - input;
  printf("Sign inversion : %d\n",answer);
  return 0;
}
しかし、このプログラムではダメです。
改行だけを入力した時に、プロンプトが表示されずに動作が止まっているように見えてしまいます。
さらに、指摘はされませんでしたが、オーバーフローのチェックがされないという問題もあります。

そこで、次の授業では入力のルーチンを強化しました。
「入力された10未満の正の整数の段数をもつピラミッドを表示する」という課題です。

CODE:

#include 

int main(void) {
	/* 数字を数値に変換するためのテーブル */
	char numberList[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
	int n;             /* ピラミッドの段数 */
	int wantInput = 1; /* 入力が必要であるというフラグ */
	int i;             /* ループ変数 */
	while(wantInput) {
		int nowNumber = 0;    /* 今入力されている整数 */
		int validFlag = 1;    /* 入力が非負整数として有効であるというフラグ */
		int overflowFlag = 0; /* 入力がオーバーフローしたというフラグ */
		char input = '\0';    /* 入力された文字 */
		printf("Input a natural number less than 10: ");
		while(input != '\n') {
			/* 入力を1文字読み込む */
			if(scanf("%c", &input) != 1) {
				printf("Unexpected end of input!\n");
				return 1;
			}
			/* 入力が改行でなかったら、処理をする */
			if(input != '\n') {
				int nowChar = -1; /* 今の数字が表す数値、数字でなければ-1 */
				for(i = 0; i  0) {
			if(overflowFlag) {
				printf("Input overflowed!\n");
			} else if(nowNumber = 1; j--) {
			printf("%d", j);
		}
		/* 改行を出力する */
		printf("\n");
	}
	return 0;
}
本題の処理より入力処理の方が長くなってしまいました。しかし、正解になったのでいいでしょう。
といっても、やはりもう少し単純に書けるといいですね。
ただし、個人的にこれまでに授業で紹介された機能しか使わない縛りをしているので、
ungetcとかerrnoとか(main以外の)自作関数とかはまだ使えません。
オフトピック
2番目のコードだけスペースインデントですが、これは仕様です。
最初はエディタのデフォルトであるスペースインデントを使用していたのですが、
エディタの表示の違いにより「インデントがおかしい」と指摘されてしまったので、
設定方法を調べてタブインデントに切り替えました。

…と思ったのですが、この日記に貼り付けるために確認したら、
なんとスペースインデントのつもりでコードを書いていたのに、タブが混ざっていました!
(ここに貼る時はスペースに修正して貼り付けました)
初期状態ではコピペのためにCtrl+Spaceを押すとOSの謎検索欄にフォーカスを取られてしまい、
コピペできないという罠もありましたし、やはり大学の授業は少し難しくなっているようですね。
でも、インターネットに接続できるのは親切設計です!

jay
記事: 314
登録日時: 13年前

Re: C言語の入力 is 難しい

投稿記事 by jay » 10年前

ピラミッドとは懐かしい
高校時代にMS-DOS入りのPC98を使って組んだ覚えがあります

思えばなんであの学校にはあんなにPC98が溢れていたんだろうか・・・