空のstdinにいくつかのヘルパ関数を宣言し、ユーザからの整数や浮動小数点を比較的安全に取得する通常の処理を行うと、これを簡単に行うことができます。たとえば、stdin
を空白にするには、'\n'
またはEOF
になるまで残りの文字をすべて読み込むだけです。
/** simple function to empty all characters that remain
* in stdin. Needed when using scanf for user input.
*/
void empty_stdin()
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
はEOF
は、ユーザーによって生成されたかどうかをチェックし、成功した変換の数(何scanf
リターン)をチェックし、あなたは、単にリターンを検証し、int
またはfloat
をユーザーに尋ね、そして最終的に場合にエラーを処理するには無効な入力が与えられ、必要に応じてempty_stdin
が入力されました。通常、ユーザーが有効な入力を提供するか、またはキャンセルするまでループします。 (無効な入力はあなたには良いことではありません)。
たとえば、整数入力を取得することは、次のように処理できます。 (注意:私はあなたのコードの本体に取り、各入力のためのコードブロックを繰り返すことから保つための機能でそれを置く...フロートのための
/** abbreviated function to read integer value from user.
* returns value on success, exits if user cancels.
* empties stdin after call to scanf.
*/
int getint()
{
int n = 0;
for (;;) { /* loop until valid input or EOF */
int rtn = 0; /* variable to capture return of scanf */
rtn = scanf ("%d", &n);
if (rtn == 1) { /* we got an integer */
empty_stdin();
break;
}
else if (rtn == EOF) { /* if user cancels, exit */
fprintf (stderr, "user canceled input.\n");
exit (EXIT_FAILURE);
}
if (rtn == 0) /* handle error */
fprintf (stderr, "getint() error: invalid integer input.\n");
empty_stdin(); /* empty all chars remaining in stdin */
}
return n;
}
(服用入力が同じように動作します) 。
最後に、あなたは一般的にちょうど原因23-bit
仮数と浮動小数点数を表現するための精度と制限の損失に、代わりにdouble
を使用して、ほとんどの場合、float
を使用しないようにしたいです。ただし、ここでは温度を使用しており、float
で十分です。
このようにまとめると、次のようなことができます。注、私はあなたがそれらを持っていたとしてmain()
前に、あなたの機能を残し、そしてmain()
後定義ヘルパー関数を追加しましたが、main()
前宣言を提供してきたので、彼らはmain()
に見える:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define NDAYS 365
typedef struct {
int day,
month;
double temperature;
} data;
float least_in_array (data *array, int n)
{
int i;
float least = INT_MAX; /* sufficiently high temp */
for (i = 0; i < n; i++)
if (array[i].temperature < least)
least = array[i].temperature;
return least;
}
float largest_in_array (data *array, int n)
{
int i;
float largest = INT_MIN; /* sufficiently low temp */
for (i = 0; i < n; i++)
if (array[i].temperature > largest)
largest = array[i].temperature;
return largest;
}
float average_array (data *array, int n)
{
int i;
float sum = 0.0;
for (i = 0; i < n; i++)
sum += array[i].temperature;
return sum/(float)n;
}
void empty_stdin();
int getint();
float getfloat();
int main (void) {
int ndx = 0;
float max = 0.0, min = 0.0, avg = 0.0;
data da[NDAYS] = {{0, 0, 0.0}};
for (;;) {
int choose = 0;
printf ("\n (1) New measurement\n"
" (2) Statistics\n"
" (3) Exit\n\n"
" choice: ");
choose = getint();
putchar ('\n');
switch (choose) {
case 1: if (ndx == NDAYS) {
fprintf (stderr, "error: array full.\n");
break;
}
printf (" Enter day in month : ");
da[ndx].day = getint();
printf (" Enter month : ");
da[ndx].month = getint();
printf (" Enter temperature : ");
da[ndx].temperature = getfloat();
printf (" da[%3d] saved\n"
" ----------------------------\n", ndx++);
break;
case 2: if (ndx == 0) {
fprintf (stderr, "error: no measurements taken.\n");
break;
}
min = least_in_array (da, ndx);
max = largest_in_array (da, ndx);
avg = average_array (da, ndx);
printf (" minimum temp : %.2f\n"
" maximum temp : %.2f\n"
" average temp : %.2f\n"
" ----------------------------\n",
min, max, avg);
break;
case 3:
goto done;
break;
default:
fprintf (stderr, "error: invalid choice.\n");
empty_stdin();
break;
}
}
done:;
return 0;
}
/** simple function to empty all characters that remain
* in stdin. Needed when using scanf for user input.
*/
void empty_stdin()
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
/** abbreviated function to read integer value from user.
* returns value on success, exits if user cancels.
* empties stdin after call to scanf.
*/
int getint()
{
int n = 0;
for (;;) { /* loop until valid input or EOF */
int rtn = 0; /* variable to capture return of scanf */
rtn = scanf ("%d", &n);
if (rtn == 1) { /* we got an integer */
empty_stdin();
break;
}
else if (rtn == EOF) { /* if user cancels, exit */
fprintf (stderr, "user canceled input.\n");
exit (EXIT_FAILURE);
}
if (rtn == 0) /* handle error */
fprintf (stderr, "getint() error: invalid integer input.\n");
empty_stdin(); /* empty all chars remaining in stdin */
}
return n;
}
/** abbreviated function to read float value from user.
* returns value on success, exits if user cancels.
* empties stdin after call to scanf.
*/
float getfloat()
{
float v = 0.0;
for (;;) { /* loop until valid input or EOF */
int rtn = 0; /* variable to capture return of scanf */
rtn = scanf ("%f", &v);
if (rtn == 1) { /* we got an float */
empty_stdin();
break;
}
else if (rtn == EOF) { /* if user cancels, exit */
fprintf (stderr, "user canceled input.\n");
exit (EXIT_FAILURE);
}
if (rtn == 0) /* handle error */
fprintf (stderr, "getint() error: invalid float input.\n");
empty_stdin(); /* empty all chars remaining in stdin */
}
return v;
}
注:コードのテイク測定部分で配列境界が365
以下に制限されていること、および統計が提供される前に少なくとも1つの測定値が存在することを確認する方法。プロセスの各ステップを常に検証する必要があります。コーナーケースを探し、何が入力に間違っているのか(猫がキーボードを踏んだ場合はどうなるか)を考え、検証とチェックを行い、それぞれのケースを処理します。上記の検証はごくわずかですが、各エラー条件をより完全にレポートして処理するために、常に追加することができます。
使用例/出力
$ ./bin/tempmxmnavg
(1) New measurement
(2) Statistics
(3) Exit
choice: 2
error: no measurements taken.
(1) New measurement
(2) Statistics
(3) Exit
choice: 1
Enter day in month : 8
Enter month : 2
Enter temperature : 20.0
da[ 0] saved
----------------------------
(1) New measurement
(2) Statistics
(3) Exit
choice: 1
Enter day in month : 9
Enter month : 2
Enter temperature : 30.0
da[ 1] saved
----------------------------
(1) New measurement
(2) Statistics
(3) Exit
choice: 1
Enter day in month : 10
Enter month : 2
Enter temperature : 70.0
da[ 2] saved
----------------------------
(1) New measurement
(2) Statistics
(3) Exit
choice: 2
minimum temp : 20.00
maximum temp : 70.00
average temp : 40.00
----------------------------
(1) New measurement
(2) Statistics
(3) Exit
choice: 3
ルック物事を超えると、ご不明な点がある場合は私に知らせて(夜与えられ、私ははるかに長くここにいないでしょうが...)
具体的にする。エラーは何ですか? 'least_in_array'の署名を見て、どのように呼び出すのかを見てください。 – Galen
宣言されていない、私は問題がどこでも関数の構造体に参加していることを知っていますが、idk、私は初心者です、私はカウントするためにint nを使用する必要があるので任意の関数で2つを要求します – jovkm
完全なエラーメッセージ。また、 'least_in_array'に関する私の前のコメントを見てください。 – Galen