У вас все еще есть небольшая проблема с определением вашего цикла управления.Вы также приглашаете Endless Loop , если во время ввода возникает ошибка соответствия , потому что вы не можете проверить возвращение scanf
(вероятно, одна из самых больших ошибок, с которыми сталкиваются новые программисты C)).Попытайся.Введите "one gallon"
в ответ на приглашение и посмотрите, что произойдет.Далее, после проверки возврата, вы должны обработать 3 случая:
scanf
можно использовать, если используется правильно.Это означает, что вы несете ответственность за проверку возврата из scanf
каждый раз .
(return == EOF)
пользователь отменил ввод, сгенерировав руководство EOF
, нажав Ctrl + d (или в окнах Ctrl + z , но см. CTRL + Z не генерирует EOF в Windows 10 (более ранние версии) ); (return < expected No. of conversions)
a , соответствующий или , на входе произошла ошибка.Для сбоя match вы должны учитывать каждый символ, оставшийся в вашем входном буфере.(сканирование вперед во входном буфере с чтением и отбрасыванием символов, пока не будет найдено '\n'
или EOF
);и, наконец, (return == expected No. of conversions)
, указывающий на успешное чтение - тогда вам нужно проверить, соответствует ли входные данные каким-либо дополнительным критериям (например, положительное целое число, положительная плавающая точка, в необходимом диапазоне и т. д.).).
На вашу логику петли.Учитывая ваш пример и ваш вопрос «Разбить оператор if внутри цикла for », я думаю, я знаю, куда вы хотите пойти - и вы можете добраться туда одним из самых простых, наименее используемых и откровенно откровенных, обязательно, выражения для управления вложенным циклом.Хорошее оле goto
утверждение.Он по-прежнему имеет место в программировании, и хотя он не должен использоваться чрезмерно, есть несколько обстоятельств, таких как те, что указаны выше, и на самом деле ваши обстоятельства, когда вполне нормально использовать goto
, чтобы выпрыгнуть из циклаи передать контроль на несколько строк вниз.(ограничение - longjmp
- вы не хотите использовать его, чтобы выпрыгнуть из функции)
Например, если я понимаю, что вы собираетесь в выживании рыбы, вы можете очиститьулучшите свою логику и включите scanf
проверки, соединив части, подобные следующему:
#include <stdio.h>
int main (void) {
double add, vol = 500;
int hour;
for (;;) { /* loop continually until valid input is received */
int rtn; /* varible for scanf return - EVERY TIME */
/* there is no conversion taking place, fputs will do */
fputs ("Please enter additional water added per hour: ", stdout);
if ((rtn = scanf ("%lf", &add)) == EOF) { /* handle EOF case */
fputs ("(user canceled input)\n", stderr);
return 1;
}
else if (rtn == 0) { /* handle matching failure */
fputs ("error: invalid double input.\n", stderr);
/* empty all characters from stdin before next input */
for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}
}
else /* handle good input */
break;
}
for (hour = 0; hour < 24; hour++) { /* loop 0 < 24 */
vol = (vol * 0.90) + add; /* adjust output hour + 1 below */
printf ("The volume is %.2f gallons after %d hours.\n", vol, hour+1);
if (vol < 100) { /* don't forget the '\n' */
printf ("The fish died after %d hours.\n", hour + 1);
goto deadfish; /* jump to deadfish label */
}
}
puts ("Alas, The fish who lived."); /* again, no conversion */
deadfish:; /* good ole goto label */
return 0;
}
( примечание: обычно цикл в C будет работать 0 < n
, и вы настраиваетевывод, как требуется выше. Хотя это не является обязательным, он очень условен, и в нем предусмотрены массивы с нулевым индексом в C, а также часы на часах, которые запускают 0 -> 23
, а не1 - > 24
. Название фильма «Нулевой темный тридцать» является хорошей аналогией (например, ноль часов тридцать минут или 12:30 am
.) Вы не можете попасть туда зацикливанием 1 <= 24
, поэтому эти ограничения не могут смоделировать концепциювремя правильно)
Обратите внимание на использование goto
.Используется вместе с проверкой vol < 100
.Если vol < 100
тестирует TRUE
, то управление передается метке , связанной с оператором goto
.(здесь обозначение deadfish:;
).Это обеспечивает несколько преимуществ здесь.Ваша петля for
может просто отслеживать время - количество часов, в течение которых бак протекает до 24
.Обратите внимание, что падение громкости ниже 100
приводит к тому, что элемент управления перепрыгивает через выход живой рыбы, который выполняется при нормальном выходе из цикла.
Хотя вы можете получить желаемый выход мертвой рыбы, включив if (vol < 100) /* print dead fish */; break; else if ...
становится очень трудно получить ваш метод /* print live fish */
при обычном выходе из цикла таким образом, без повторной проверки счетчика цикла как части предложения else if
.goto
предоставляет элегантное решение именно этой проблемы, позволяя вам передавать управление в случае /* print live fish */
, когда громкость падает ниже предела, в то же время сохраняя нормальный выход из цикла без необходимости проверять переменную счетчика цикла.во второй раз внутри самого цикла.
Пример Использование / Вывод
Убедитесь, что ваша программа может обрабатывать нажатие кошки на клавиатуре для каждого пользовательского ввода.Вы должны проверять каждый раз, например,
$ ./bin/deadfish
Please enter additional water added per hour: one gallon
error: invalid double input.
Please enter additional water added per hour: 1
The volume is 451.00 gallons after 1 hours.
The volume is 406.90 gallons after 2 hours.
The volume is 367.21 gallons after 3 hours.
The volume is 331.49 gallons after 4 hours.
The volume is 299.34 gallons after 5 hours.
The volume is 270.41 gallons after 6 hours.
The volume is 244.37 gallons after 7 hours.
The volume is 220.93 gallons after 8 hours.
The volume is 199.84 gallons after 9 hours.
The volume is 180.85 gallons after 10 hours.
The volume is 163.77 gallons after 11 hours.
The volume is 148.39 gallons after 12 hours.
The volume is 134.55 gallons after 13 hours.
The volume is 122.10 gallons after 14 hours.
The volume is 110.89 gallons after 15 hours.
The volume is 100.80 gallons after 16 hours.
The volume is 91.72 gallons after 17 hours.
The fish died after 17 hours.
(тест на клавиатуре пройден ...)
Ближайшая мертвая рыба к 100 галлонам:
$ ./bin/deadfish
Please enter additional water added per hour: 6.53
The volume is 456.53 gallons after 1 hours.
The volume is 417.41 gallons after 2 hours.
The volume is 382.20 gallons after 3 hours.
The volume is 350.51 gallons after 4 hours.
The volume is 321.99 gallons after 5 hours.
The volume is 296.32 gallons after 6 hours.
The volume is 273.22 gallons after 7 hours.
The volume is 252.42 gallons after 8 hours.
The volume is 233.71 gallons after 9 hours.
The volume is 216.87 gallons after 10 hours.
The volume is 201.71 gallons after 11 hours.
The volume is 188.07 gallons after 12 hours.
The volume is 175.79 gallons after 13 hours.
The volume is 164.75 gallons after 14 hours.
The volume is 154.80 gallons after 15 hours.
The volume is 145.85 gallons after 16 hours.
The volume is 137.80 gallons after 17 hours.
The volume is 130.55 gallons after 18 hours.
The volume is 124.02 gallons after 19 hours.
The volume is 118.15 gallons after 20 hours.
The volume is 112.86 gallons after 21 hours.
The volume is 108.11 gallons after 22 hours.
The volume is 103.83 gallons after 23 hours.
The volume is 99.97 gallons after 24 hours.
The fish died after 24 hours.
(3 - 100-я мертвых галлона)
Первая живая рыба:
$ ./bin/deadfish
Please enter additional water added per hour: 6.54
The volume is 456.54 gallons after 1 hours.
The volume is 417.43 gallons after 2 hours.
The volume is 382.22 gallons after 3 hours.
The volume is 350.54 gallons after 4 hours.
The volume is 322.03 gallons after 5 hours.
The volume is 296.36 gallons after 6 hours.
The volume is 273.27 gallons after 7 hours.
The volume is 252.48 gallons after 8 hours.
The volume is 233.77 gallons after 9 hours.
The volume is 216.94 gallons after 10 hours.
The volume is 201.78 gallons after 11 hours.
The volume is 188.14 gallons after 12 hours.
The volume is 175.87 gallons after 13 hours.
The volume is 164.82 gallons after 14 hours.
The volume is 154.88 gallons after 15 hours.
The volume is 145.93 gallons after 16 hours.
The volume is 137.88 gallons after 17 hours.
The volume is 130.63 gallons after 18 hours.
The volume is 124.11 gallons after 19 hours.
The volume is 118.24 gallons after 20 hours.
The volume is 112.95 gallons after 21 hours.
The volume is 108.20 gallons after 22 hours.
The volume is 103.92 gallons after 23 hours.
The volume is 100.07 gallons after 24 hours.
Alas, The fish who lived.
(спасенный 7 - 100-ым галлоном - я оставлю это вам, чтобы разделить дальше на 1000-ый галлон, если вам нужно)
Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.Поместите goto
в свой набор инструментов C, зная, что его не следует использовать чрезмерно, но у него есть несколько применений, где он может обеспечить оптимальное решение, и в случае разрыва вложенного цикла это единственный инструмент в вашем наборе инструментов, которыймогу это сделать.