Плохо читать char c
с scanf("%s", &c);
. "%s"
требуется буфер для хранения строки. Единственная строка, которая вписывается в char
- это пустая строка (состоящая только из терминатора '\0'
- не очень полезна). Каждая строка с 1 символом требует 2 char
с хранения & ndash; 1 для символа, 1 для терминатора ('\0'
). char
для хранилища: Неопределенное поведение .
Итак, первая подсказка заключалась в том, чтобы вместо этого использовать правильный форматер & ndash; "%c"
.
Это лучше, так как удаляет неопределенное поведение. Тем не менее, это не решает другую проблему, как показано в следующем примере:
#include <stdio.h>
int cont()
{
char c; do {
printf("Continue (y/n): ");
scanf("%c", &c);
printf("Input %c\n", c);
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}
Выход:
Loop iteration 1.
Continue (y/n): <b>y↵</b>
Input 'y'
Loop iteration 2.
Continue (y/n):
Input '
'
Continue (y/n): <b>n↵</b>
Input 'n'
Демонстрация в реальном времени на ideone
WTH?
scanf("%c")
потребляет один символ из ввода. Другой символ (вставленный для клавиши ENTER ) остается в буфере ввода до следующего вызова любой функции ввода.
Жаль, без ENTER трудно подтвердить ввод на консоли.
Возможным решением является чтение символов до тех пор, пока не будет получена клавиша ENTER (или по каким-либо причинам произойдет сбой ввода). (И, между прочим, getc()
или fgetc()
могут также использоваться для чтения одного символа.):
#include <stdio.h>
int cont()
{
int c;
do {
int d;
printf("Continue (y/n): ");
if ((c = fgetc(stdin)) < 0) {
fprintf(stderr, "Input failed!\n"); return 0;
}
printf("Input '%c'\n", c);
for (d = c; d != '\n';) {
if ((d = fgetc(stdin)) < 0) {
fprintf(stderr, "Input failed!\n"); return 0;
}
}
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}
Выход:
Loop iteration 1.
Continue (y/n): <b>y↵</b>
Input 'y'
Loop iteration 2.
Continue (y/n): <b>Hello↵</b>
Input 'H'
Continue (y/n): <b>n↵</b>
Input 'n'
Демонстрация в реальном времени на ideone
Обратите внимание, что я изменил тип прочитанного символа на int
. Это потому, что getc()
/ fgetc()
возвращает int
, который способен хранить любое из 256 возможных значений char
, а также -1
, который возвращается в случае сбоя.
Однако не составляет труда сравнить int
с символьной константой (например, 'y'
). В C тип символьных констант просто int
( SO: Тип символьной константы ).