2013-02-13 3 views
0

Я совершенно новый в программировании, и я недавно нашел этот сайт, чтобы помочь обучить себя. Я пытаюсь сделать программу с помощью «C», которая запрашивает оценки в трех разных категориях в моей книге. Я столкнулся с высказываниями и понял, где у меня лучший выбор для этого. Мой текущий код выглядит примерно так.Как использовать в то время как петли

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); 
} 

Теперь то, что я пытаюсь сделать после этой точки повторить процесс еще два раза, однако, когда я пытаюсь запустить ехе я получаю первую часть, чтобы бежать, но две другие части просто не получают воспитывался по какой-то причине. Это просто делается для ограничения того, что делают заявления повторения? или у меня есть ошибка где-то. Я пытаюсь понять, что я делаю неправильно, но я просто вижу это.

Я не совсем уверен, как правильно разместить сообщение здесь, но это пример вывода, который я получаю.

вот пример моего вывода, так как вы можете видеть, что он запрашивает у меня 1-й сегмент, который является частью назначения, но после ввода -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 

Я полагаю, что по крайней мере первая часть работает, но после того, как я получаю общее я не запрошен следующий вид спрашивает для классов экзамена.

+0

Пожалуйста вывесить выход. Я подозреваю, что вы не видите приглашение, потому что вам нужно вызвать 'fflush (stdout)'. Множество терминалов буферизируется по строке и не будет выводить вывод на экран по умолчанию, если вы не напишете новую строку (или явно скрытую). – paddy

+1

Работает отлично на моем Mac (clang) и Windows (vc2012). – WhozCraig

+0

Сложно представить любую библиотеку ввода/вывода C, которая не выдает вывод перед чтением ввода. –

ответ

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); 

Теперь это делает больше повторений. Было бы лучше, если бы вам только нужно было написать приглашение один раз, а не дважды для каждого цикла. Вы можете обойти это, просто инициализируя 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, чтобы отменить тот факт, что вы увеличиваете его в верхней части петли. Все это начинает чувствовать себя немного неуклюжим.

Другая проблема заключается в том, что если пользователь вводит то, что не является целым числом, ваша программа будет создавать неопределенное поведение (потому что вы фактически не инициализируете 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); 
} 
+0

Спасибо за помощь, я пытаюсь понять большую часть того, что вы сказали мне здесь, и поэтому мне может потребоваться некоторое время, чтобы я это понял, но я должен спросить, разрешит ли я продолжать вводить данные после того, как раздел Assignment были введены? – Ruisu

Смежные вопросы