9.7 KiB
9.7 KiB
title | author | date | url | wordtwit_post_info | categories | |||
---|---|---|---|---|---|---|---|---|
『新版C言語プログラミングレッスン 入門編』の勉強 | kazu634 | 2008-03-18 | /2008/03/18/_914/ |
|
|
頑張ってみるけど、「プロフェッショナルの流儀」が始まるまで。
ユーザーからのインプットを待って対話的なプログラム
#include <stdio.h> #include <stdlib.h> #define MAXLINE 256 int main(void); int main(void) { char buffer[MAXLINE]; int age; printf ("Please enter your name.\n"); gets(buffer); printf ("Hi, %s.\n", buffer); printf ("Please enter your age.\n"); gets(buffer); age = atoi(buffer); printf ("You are now %d, so you will be %d in 10 years!\n", age, age + 10); return(); }
- C の文字列 (char) は、変数一つにつき一文字しか格納できないよ
- atoi は ascii to integer (Ascii文字から整数型へ)という意味
- gets は標準出力からユーザーのインプットを待つ命令
九九
とりあえず打ち込んでみた。
/* 名前:九九練習プログラム */ /* 書式:九九を練習する */ /* 解説: */ /* プログラムkukuは、九九の問題をランダムに20個表示して */ /* その正答数と正解率を表示するプログラムです。 */ #include <stdio.h> #include <stdlib.h> #include <time.h> #define MAX_Q 20 /* 表示する問題の個数 */ #define MAX_LINE 128 /* 入力行の最大長 */ int main(void); void kuku(int questno); int good_answers = ; /* 正答の数 */ /* 関数mainは九九の練習をする。 */ /* 問題をMAX_Q回繰り返す。 */ /* 最後に結果を表示する。 */ int main(void) { int i; float rate; /* 現在時刻を使って乱数の「種」を得る */ srand((unsigned int)time(NULL)); printf ("これから九九の問題を %d 問出します。\n", MAX_Q); good_answers = ; for (i = ;i < MAX_Q;i++) { kuku(i); } rate = good_answers * 100.0 / MAX_Q; printf ("問題は %d 問ありました。\n", MAX_Q); printf ("%d 問は正しく答えられましたが、\n", good_answers); printf ("%d 問は間違っていました。\n", MAX_Q - good_answers); printf ("正答率 %0.1f %% です。\n", rate); printf ("\n"); printf ("お疲れ様。\n"); return(); } /* 関数kukuは九九の問題を一問出して、答えを待つ。 */ /* 正答、誤答の別を表示する。 */ void kuku(int questno) { int x, y, result; char buffer[MAX_LINE]; x = rand() % 9 + 1; y = rand() % 9 + 1; printf ("[Question No. %d] %d × %d =", questno +1, x, y); fflush(stdout); gets(buffer); result = atoi(buffer); if ( x * y == result) { printf ("Your answer is correct.\n"); good_answers++; } else { printf ("Your answer is wrong.\n"); } printf ("\n"); }
id:maq さんのコメントを読んで、「オーバーフロー」について調べる。
C ユーザは、確保されている領域を越えることはありえないと確証できなければ、 境界をチェックしない危険な関数を使うべきではありません。 通常使用を避けた方が良い(確実に防御すべき)関数には、strcpy(3)や strcat(3)、 sprintf(3)(親戚に当たる vsprintf(3))、gets(3) があります。 その代わりとして、strncpy(3)や、strncat(3)、snprintf(3)や fgets(3)の使用を お薦めします。詳しくは下記で論じますので読んでください。
ということらしい。そういえば、gccでコンパイルしたら「gets使わない方がいいよ」的な警告が出ていたような。とりあえず現状、こういう難しい問題はひとまず置いておいて『新版C言語プログラミングレッスン 入門編』に準拠して勉強を進めていこうと考えてますです。
コメントありがとうございます(__)