При выполнении последнего упражнения в главе 7, столкнулся с проблемой считывания строки ввода, если в ней встречается перевод строки. Везде это объясняется несколько заумно, попробую на пальцах:
Проблема в том, что когда вы вводите с клавиатуры в scanf любой ввод — помимо символов (букв, цифр и проч) — вы также _всегда_ отправляете во входящий поток символ /n — то бишь перевод строки.
К примеру, в программе стоит оператор scanf ("%c", &n);
Вы нажимаете на клавиатуре клавишу q, а затем клавишу Enter, чтобы отправить значение в программу…
Что при этом оказывается в программе? Логично предположить, что там теперь будет только q. Действительно, q становится значением переменной n. Но на самом деле кое-что еще — вы отправили в поток ввода (он еще зовётся stdin) и клавишу Enter, которую можно интерпретировать как \n.. Возьмем еще один пример:
#include <stdio.h>
int main (void)
{
int z, x;
scanf ("%c", &z);
printf("%c", z);
scanf ("%c", &x);
printf("%c", x);
return 0;
}
Теперь запустим программу и…
- Нажмем клавишу
a, затем нажмем клавишуEnter - На экран будет выведен символ
a - Теперь нажмем клавишу
b, затем нажмем клавишуEnter - На экран не будет выведена
b, будет лишь пустая строка
А вот таже самая ситуация глазами программы:
- Запрашиваю значение переменной
z - Пользователь вводит
aи\n - Присваиваю переменной
zзначениеa - Вывожу на экран
a - Запрашиваю значение переменной
x - Пользователь вводит
bи\n - Вижу, что в входном потоке находится
\nb\n - Беру следующий символ из потока ввода:
\nи присваиваю его переменнойx - Вывожу на экран символ новой строки (
\n) - При этом в потоке все также остаются
b\n
…которые так и будут вечно лежать в этом буфере (так называют входной поток, который уже сохранен в памяти программы).
Что делать, чтобы таких ошибок не возникало?
- помнить, что
scanf(и само собойgetchar) не пропускает служебные символы (в том числе\n) при вводе символов%c, а также%[…]и%n. В остальных случаях можно не париться, к примеру,scanf ("%d", x)— не обращает на\nвнимания (поэтому ни в коем случае не используйте что-то вродеscanf ("%d\n", x)). - чистить буфер. Как говорится: чистота — залог здоровья (пойти принять душ что ли?). Для этого есть много способов, начинающим рекомендую делать так:
while (getchar() != '\n') continue;
Что при этом происходит — цикл вынимает по одному символы из входного потока и сравнивает — не перенос ли это строки. Если нет — то он переходит к
continue;, которая возвращает программу в начало цикла и снова достает еще один символ и снова сравнивает. И так до тех пор, пока не встретит\n; при этом, когда он таки встретит\n— цикл уже его из буфера достанет (т.е. буфер очистит, он станет пустым), и цикл прекратится → ваша программа продолжит выполнение.Есть и другие способы чистки буфера, например, функция
fflush(stdin), однако перед тем, как ее использовать обязательно ознакомьтесь с документацией.
Буду рад вашим комментариям!

Символьный пробел перед спецификатором в ф-ции scanf() позволяется обойтись от цикла while.
#include
int main (void)
{
char z, x;
// Запрос первого символа
printf(«Enter the first letter: «);
scanf (» %c», &z); printf(«%c\n», z);
// Запрос второго символа
printf(«Enter the second letter: «);
scanf (» %c», &x); printf(«%c», x);
printf(«\nThe program is completed.\n»);
return 0;
}