0

私はプログラミングがまったく初めてで、最近このサイトを見つけて自己啓発に役立てています。「C」を使用して、本の中で3つの異なるカテゴリの成績を求めるプログラムを作成しようとしています.whileステートメントに遭遇し、これを行うのに最適な場所を見つけました。私の現在のコードは次のようになります。

int countA;
int gradeA;
int totalA;
int weightA;
float averageA;

int countE;
int gradeE;
int totalE;
int weightE;
float averageE;

int countQ;
int gradeQ;
int totalQ;
int weightQ;
float averageQ;

totalA = 0;
countA = 0;

totalE = 0;
countE = 0;

totalQ = 0;
countQ = 0;

printf( "Enter Assignment Grade, -1 to end: "); /* prompt for input */
scanf( "%d", &gradeA );

while (gradeA != -1){
totalA = totalA + gradeA; /* add gradeA to totalA */
    countA = countA + 1;
        printf( "Enter Assignment Grade, -1 to end: "); /* prompt for input */
        scanf( "%d", &gradeA );
}
if (countA != 0) {
averageA = (float) totalA / countA;
printf( "total is %.2f\n", averageA );
}



printf( "Enter Exam Grade, -1 to end: "); /* prompt for input */
scanf( "%d", &gradeE );

while (gradeE != -1){
totalE = totalE + gradeE; /* add gradeE to totalE */
    countE = countE + 1;
        printf( "Enter Exam Grade, -1 to end: "); /* prompt for input */
        scanf( "%d", &gradeE );
}
if (countE != 0) {
averageE = (float) totalE / countE;
printf( "total is %.2f\n", averageE );
}


printf( "Enter Quiz Grade, -1 to end: "); /* prompt for input */
scanf( "%d", &gradeQ );

while (gradeQ != -1){
totalQ = totalQ + gradeQ; /* add gradeQ to totalQ */
    countQ = countQ + 1;
        printf( "Enter Quiz Grade, -1 to end: "); /* prompt for input */
        scanf( "%d", &gradeQ );
}
if (countQ != 0) {
averageQ = (float) totalQ / countQ;
printf( "total is %.2f\n", averageQ );
}

この時点で私がやろうとしているのは、プロセスをさらに2回繰り返すことですが、exeを実行しようとすると、最初の部分が実行されますが、他の2つの部分は何らかの理由で起動しません. これは単に while ステートメントが行うことを制限するためのものですか? または、どこかにエラーがありますか。私は自分が間違っていることを理解しようとしていますが、それを見るだけです。

ここに適切に投稿する方法についてはまだよくわかりませんが、これは私が得た出力の例です。

これは私の出力の例です。割り当て部分である最初のセグメントを求めるプロンプトが表示されますが、ループを終了するために -1 を入力すると、平均が得られて終了します。

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>project1.exe
Enter Assignment Grade, -1 to end: 100
Enter Assignment Grade, -1 to end: 80
Enter Assignment Grade, -1 to end: 77
Enter Assignment Grade, -1 to end: 33
Enter Assignment Grade, -1 to end: 76
Enter Assignment Grade, -1 to end: 92
Enter Assignment Grade, -1 to end: -1
total is 76.33

少なくとも最初の部分は機能していると思いますが、合計を取得した後、次の外観を求められず、試験の成績を求められます。

4

1 に答える 1

2

発生する可能性のある一般的な問題は、出力バッファリングです。コードの場合:

printf( "Enter Assignment Grade, -1 to end: "); /* prompt for input */
scanf( "%d", &gradeA );

端末が出力バッファを画面にフラッシュしない場合があります。そのため、入力を待ちますが、プロンプトが表示されない場合があります。それを強制するには、これを行うことができます:

printf( "Enter Assignment Grade, -1 to end: "); /* prompt for input */
fflush(stdout);
scanf( "%d", &gradeA );

さて、それはより多くの繰り返しになります。ループごとに2回ではなく、1回だけプロンプトを作成する必要があるとよいでしょう。gradeAループの前にゼロに初期化するだけで、これを回避できます。その場合、ループ内の最初の計算は効果がありません。

gradeA = 0;
totalA = -1;

while (gradeA != -1)
{
    totalA = totalA + gradeA;
    countA = countA + 1;
    printf( "Enter Assignment Grade, -1 to end: ");
    fflush(stdout);
    scanf( "%d", &gradeA );
}

countEループの先頭でインクリメントするという事実を元に戻すために-1に設定していることに注意してください。これはすべて少し不器用に感じ始めます。

もう1つの問題は、ユーザーが整数以外のものを入力すると、プログラムが未定義の動作を生成することです(実際には初期化しないためgradeA)。scanf読み取ったアイテムの数が返されるため、成功したかどうかをテストできます。

怠惰なアプローチはこれです:

if( 1 != scanf( "%d", &gradeA ) ) {
    printf( "Invalid input!"\n" );
    exit(1);
}

あなたが決めることができます。残りの答えについては、それを無視します。

ループを強化すると、コードの繰り返しがテーマであることが明らかになります。変更するのは変数とプロンプトだけです。それで、それを関数に変える時が来たかもしれません:

int grade_average( const char *what, int *total, float *average )
{
    int count = -1;
    int grade = 0;
    *total = 0;

    while( grade != -1 )
    {
        count++;
        *total += grade;

        printf( "Enter %s Grade, -1 to end: ", what );
        fflush(stdout);

        if( 1 != scanf("%d", &grade) ) return 0;  // fail on input error.
    }

    if( count > 0 ) {
        *average = (float)*total / count;
    }

    return 1;
}

今、あなたはこのように呼び出すことができます:

if( grade_average("Assignment", &totalA, &averageA) ) {
    printf( "Total is %.2f\n", averageA );
}

if( grade_average("Exam", &totalE, &averageE) ) {
    printf( "Total is %.2f\n", averageE );
}

if( grade_average("Quiz", &totalQ, &averageQ) ) {
    printf( "Total is %.2f\n", averageQ );
}
于 2013-02-13T22:41:52.840 に答える