Как реализовать ввод целых чисел в бесконечном цикле?
Задание: По двум введенным целым числам (день и месяц) вывести количество дней, оставшихся до Нового года (считать, что в феврале 28 дней), двумя способами: a) используя конструкцию switch ... case.
/* Online C Compiler and Editor */
#include <stdio.h>
int main()
{
int d,m,td,tm;
do{
printf("vedite days: ");
td=scanf("%d",&d);
printf("vedite mesac: ");
tm=scanf("%d",&m);
if ((tm!=0)&&(td!=0)){
if ((0<m<13)&&(0<d<32)){
switch(m){
case 2:
if (!(d<29)){
td=0;
break;
}
case 4:
if (!(d<31)){
td=0;
break;
}
case 6:
if (!(d<31)){
td=0;
break;
}
case 9:
if (!(d<31)){
td=0;
break;
}
case 11:
if (!(d<31)){
td=0;
break;
}
default: break;
}
}
else{
td=0;
tm=0;
}
}
}while(td==0 && tm==0);
switch(m){
case 1: printf("%d\n",365-d+1); break;
case 2: printf("%d\n",334-d+1); break;
case 3: printf("%d\n",306-d+1); break;
case 4: printf("%d\n",275-d+1); break;
case 5: printf("%d\n",245-d+1); break;
case 6: printf("%d\n",214-d+1); break;
case 7: printf("%d\n",184-d+1); break;
case 8: printf("%d\n",153-d+1); break;
case 9: printf("%d\n",122-d+1); break;
case 10: printf("%d\n",92-d+1); break;
case 11: printf("%d\n",61-d+1); break;
case 12: printf("%d\n",31-d+1); break;
default: printf("no"); break;
};
return 0;
}
Первая часть кода, это проверка на "дурака", с ней у меня и возникли сложности. Если пользователь вводит день и месяц, которого не существует, то первый цикл должен это проверить и попросить пользователя ввести еще раз ввести день/месяц. Проблемы с которыми я столкнулся: когда я ввожу символы, а не числа, то у меня бесконечно выводится printf("vedite days: ");
и printf("vedite mesac: ");
не давая возможности ввести день/месяц; когда я вожу не существующий день/месяц первый цикл завераештся и считает количество дней (второй switch, доходит до default и выводит "no"). Я только начал изучать С, прошу отнестить с пониманием.
Ответы (2 шт):
1)По поводу бесконечного цикла, если упростить, то вводя символ, он никуда не девается, он со следующей итерацией пытается куда-то попасть. Например, мы ввели 'a', первый scanf() возвращает 0, символ по-прежнему никуда не пропал, поэтому он пытается записаться во втором scanf() и так же возвращает 0. С новой итерацией он никуда не пропадает и так по кругу. Вот один из вариантов решения проблемы:
`while ((td = scanf("%d",&d)) != 1){
while (getchar() != '\n')
{
continue;
}
printf("Неправильный ввод. Попробуйте ещё раз!\n");
printf("vedite days: ");
}`
Суть в том, что функция getchar() ловит символы, пока не словит символ новой строки '\n' (он у нас появился при нажатии Enter, scanf() его если что пропускает, но нам нужен маркер окончания цикла).
2)В первом switch() добавьте tm = 0; в каждый case, так как условие while() не удовлетворяется или можна сделать while(td==0 || tm==0).
Вот, что в итоге у меня получилось:
#include<stdio.h>
int main ()
{
int d,m,td,tm,fl;
char c;
do{
fl=0;
do{
printf("vedite days: ");
td=scanf("%d",&d);
while ((c=getchar())!=EOF && c!='\n');
}while(td!=1);
do{
printf("vedite mesac: ");
tm=scanf("%d",&m);
while ((c=getchar())!=EOF && c!='\n');
}while(tm!=1);
if (((0<m)&&(m<13))&&((0<d)&&(d<32))){
fl=1;
switch(m){
case 2:
if (!(d<29)){
fl=0;
break;
}
case 4:
if (!(d<31)){
fl=0;
break;
}
case 6:
if (!(d<31)){
fl=0;
break;
}
case 9:
if (!(d<31)){
fl=0;
break;
}
case 11:
if (!(d<31)){
fl=0;
break;
}
default: break;
}
}
}while(fl==0);
int x[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int t=365;
for(int i = 0; i < m-1; i++){
t=t-x[i];
}
printf("До Нового Года осталось %d дней\n",t-d);
return 0;
}