Распространённые ошибки ввода-вывода
Проблемы буфера и перевода строки
«Распространённые ошибки ввода-вывода» — бесплатный урок C Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C Academy содержит 4 уроков всего.
Распространённые ошибки ввода-вывода
Ввод и вывод в C таят несколько классических ловушек. Знание этих ловушек сэкономит вам часы отладки.
#include <stdio.h>
int main(void) {
printf("Let us study I/O pitfalls\n");
return 0;
}Оставшийся перевод строки
После scanf("%d", ...) клавиша Enter оставляет в буфере \n. Последующий %c считывает этот перевод строки вместо настоящего ввода.
#include <stdio.h>
int main(void) {
char c = 'A';
printf("Use a space before %%c to skip the leftover newline\n");
printf("c = %c\n", c);
return 0;
}Исправление с помощью пробела
Запись scanf(" %c", &c) с пробелом в начале сообщает scanf, что сначала нужно пропустить пробельные символы.
#include <stdio.h>
int main(void) {
char c = 'Z';
printf("scanf(\" %%c\", &c) skips whitespace\n");
printf("c = %c\n", c);
return 0;
}Забытый амперсанд
Передача переменной в scanf без & приводит к записи по неверному адресу и, скорее всего, к сбою.
#include <stdio.h>
int main(void) {
int n = 9;
printf("Always pass &n, not n, to scanf for an int\n");
printf("n = %d\n", n);
return 0;
}Несоответствующие спецификаторы
Считывание double с помощью %f вместо %lf в scanf повреждает значение. Для вывода используется %f в обоих случаях, но для ввода спецификаторы различаются.
#include <stdio.h>
int main(void) {
double d = 2.5;
printf("scanf needs %%lf for double; printf uses %%f\n");
printf("d = %.1f\n", d);
return 0;
}Буферизация вывода
Вывод может буферизоваться и не появляться сразу. Завершение строкой \n или вызов fflush(stdout) очищает буфер.
#include <stdio.h>
int main(void) {
printf("Flushed by newline\n");
fflush(stdout);
return 0;
}gets опасна
Старая функция gets не проверяла границы и удалена из современного C. Вместо неё используйте fgets.
#include <stdio.h>
int main(void) {
char buf[10];
/* fgets(buf, sizeof buf, stdin); */
buf[0] = 'H'; buf[1] = 'i'; buf[2] = 0;
printf("buf = %s\n", buf);
return 0;
}Переполнение буфера с %s
Обычный %s в scanf может записать данные за пределы небольшого массива. Ограничьте его ширину, например %19s.
#include <stdio.h>
int main(void) {
char name[20];
printf("Use %%19s to leave room for the null terminator\n");
name[0] = 0;
printf("name length cap protects buffer\n");
return 0;
}fgets сохраняет перевод строки
fgets сохраняет завершающий перевод строки. Часто его необходимо удалить.
#include <stdio.h>
#include <string.h>
int main(void) {
char line[] = "hello\n";
line[strcspn(line, "\n")] = 0;
printf("[%s]\n", line);
return 0;
}Игнорирование возвращаемых значений
Если не проверять возвращаемое значение scanf, некорректный ввод незаметно проходит дальше. Всегда выполняйте проверку.
#include <stdio.h>
int main(void) {
int n = 3;
int items = 1;
if (items != 1)
printf("bad input\n");
else
printf("ok: %d\n", n);
return 0;
}Безопасная сборка всего вместе
Надёжный подход: считывайте данные с помощью fgets, разбирайте их с помощью sscanf и проверяйте результат.
#include <stdio.h>
int main(void) {
char line[] = "123";
int n;
if (sscanf(line, "%d", &n) == 1)
printf("parsed %d\n", n);
return 0;
}Быстрая проверка
Проверьте своё понимание проблем ввода-вывода.
Итоги: распространённые проблемы ввода-вывода
Вы научились избегать распространённых ошибок.
- Оставшиеся переводы строк мешают
%c; используйте пробел в начале - Всегда передавайте адреса с помощью
& - Используйте
%lfдля считывания значений double - Предпочитайте
fgetsфункцииgetsи ограничивайте ширину%s - Проверяйте возвращаемые значения и очищайте буфер вывода
Изучай C с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 39
- Уроки
- 144
Часто задаваемые вопросы
Урок «Распространённые ошибки ввода-вывода» бесплатный?
Да — полный текст урока «Распространённые ошибки ввода-вывода» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C Academy, подпишись на CoddyKit PRO. Курс C Academy содержит 4 уроков всего.
Чему я научусь в уроке «Распространённые ошибки ввода-вывода»?
Проблемы буфера и перевода строки Ты практикуешь C Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C Academy?
Предыдущий опыт не требуется. C Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Распространённые ошибки ввода-вывода»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C Academy?
Да. Каждый урок C Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Спецификаторы формата printf
- scanf и ввод
- Ширина, точность и флаги
- Распространённые ошибки ввода-вывода