54章 時間と乱数

http://www.geocities.jp/ky_webid/c/054.html

ライブラリ関数の紹介ですね。

今回は時間関係の関数と乱数についてのお話のようです。

ここで覚えることは以下ですね。

  • tm構造体
  • time_t型
  • clock_t型
  • time関数
  • ctime関数
  • localtime関数
  • mktime関数
  • rand関数
  • srand関数


多いっすねorz

そろそろ言語の仕様というよりもこういったライブラリの紹介が多くなってきましたね。

これらの関数は記事を分けて少しずつやっていこうと思います。

とりあえずは練習問題にチャレンジです。

問題1

乱数を使って、1〜6の値をランダムで表示させるプログラムを作って下さい。(サイコロですね)

ランダム要素のからんだプログラムですね。今回が初めてなので少しどきどきしています。

int main () {
    int i;
    
    srand( (unsigned)time(NULL) );
    
    for(i=0;i<100;++i) {
        printf("%d ",rand() % 6 + 1);
    }
    
    return 0;
}
$ main
2 3 2 4 5 6 2 6 1 2 1 6 3 4 6 5 4 1 6 5 4 1 2 5 4 1 6 1 2 4 4 6 4 2 1 2 3 5 3 2
3 6 3 4 2 3 5 4 1 6 4 1 1 4 3 5 6 1 4 6 4 1 5 4 5 2 5 2 4 5 1 3 5 2 3 6 3 2 1 5
3 3 6 4 1 6 6 3 6 4 1 3 2 4 6 4 4 5 3 6

実際は一行で出力されてますが長いので改行しています。

ちょっと迷いましたが、できました。出力したい範囲の数で割った余りを求めれば完成ですね。今回は1〜6なので+1しています。

答え合わせ

完璧!あってました。

問題2

キーボードから入力された西暦から、現在の西暦までの年数を求めるプログラムを作って下さい。

やってみます。

int main () {
    struct tm *now;
    time_t t;
    unsigned int year;
    
    scanf("%d",&year);
    
    t = time(NULL);
    now = localtime(&t);
    now->tm_year += 1900;
    
    printf("%d - %d = %d",now->tm_year,year,now->tm_year - year);
    
    return 0;
}
$ main
1980
2009 - 1980 = 29

$ main
2008
2009 - 2008 = 1

$ main
1800
2009 - 1800 = 209

できました。ちゃんと出力されていますね。

答え合わせ

ばちこいあってました。良かったです。

問題3

画面に適当な小文字のアルファベットを1文字表示し、それをキーボードから入力させます。入力にかかった時間を秒単位で表示させるプログラムを作って下さい。また、入力を間違えた場合には、それを伝えるメッセージを表示させるようにして下さい。

おお、なんだかプログラムらしくなってきましたね。やってみます!

int main () {
    char str[2];
    clock_t start;
    int i;
    time_t t;
    
    start = clock();
    
    // 'a'=97; 'z'=122;
    srand((unsigned)time(NULL));
    i = rand() % ('z' - 'a') + 'a';
    
    printf("%c を入力してください\n",i);
    fgets(str,sizeof(str),stdin);
    
    if ( str[0] != i ) {
        puts("入力エラーです");
        return 1;
    }
    
    printf("%s を入力するまでにかかった時間 %d秒",str,(clock() - start) / CLOCKS_PER_SEC);
    return 0;
}
$ main
i を入力してください
i
i を入力するまでにかかった時間 1秒

$ main
v を入力してください
a
入力エラーです

エクセレント。面白くなってきました。うまく動いています。

答え合わせ

ありゃ。ちょっとだけ違いましたね。

僕はてっきりclock使うものだと思って使ったんですが、解答例では普通にtimeで取得した値を利用して計算してますね。

基本的にはtimeを使ったほうが良いのかもしれません。今度からそうします。