Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Поскольку функция fgets() обрабатывает символ новой строки как часть строки (при условии, что строка ввода имеет соответствующую длину), ее часто применяют совместно с функцией fputs(), которая работает подобно puts(), но не добавляет автоматически символ новой строки. Функция fputs() принимает второй аргумент, указывающий на файл, в который должна производиться запись. Для вывода на дисплей можно использовать аргумент stdout (от standard output — стандартный вывод).
В листинге 11.7 иллюстрируется поведение функций fgets() и fputs().
Листинг 11.7. Программа fgetsl. с
Ниже показаны результаты пробного запуска:
Введите строку, шарлотка
Ваша строка, выведенная дважды (с помощью puts(), а затем fputs()): шарлотка
шарлотка
Введите еще одну строку, клубничное песочное печенье
Ваша строка, выведенная дважды (с помощью puts() , а затем fputs()) : клубничное пес клубничное песГотово.
Первая строка ввода, шарлотка, является достаточно короткой, чтобы функция fgets() прочитала ее и сохранила шарлотка\n\0 в массиве. Поэтому, когда функция puts() отображает строку и добавляет в вывод собственный символ новой строки, она порождает пустую строку вывода после строки шарлотка. Так как fputs() не добавляет символа новой строки, она не создает пустую строку.
434 глава 11
Длина второй строки ввода, клубничное песочное печенье, превышает лимит на размер, поэтому fgets() считывает первые 14 символов и сохраняет в массиве строку клубничное пес\0. И снова функция puts() добавляет символ новой строки в вывод, a fputs() не делает этого.
Функция fgets() возвращает указатель на char. Если все проходит нормально, она просто возвращает тот же адрес, который был ей передан в первом аргументе. Однако если функция встречает конец файла, она возвращает специальный указатель, называемый нулевьш.. Такой указатель гарантированно не ссылается на реальные данные, поэтому может применяться для отражения особого случая. В коде он может быть представлен цифрой 0 или, что более распространено в С, макросом NULL. (Функция возвращает NULL также в ситуации, когда произошла какая-то ошибка чтения.) В листинге 11.8 показан простой цикл, который читает и повторяет текст до тех пор, пока функция fgets() не встретит конец файла или не выполнит считывание пустой строки — т.е. строки, первым символом которой является символ новой строки.
Листинг 11.8. Программа fgets2.c
Вот как выглядит вывод из этой программы:
Введите строки (или пустую строку для выхода из программы) :
Кстати говоря, функция gets ()
Кстати говоря, функция gets() также возвращает пустой ухазатель, если онатакже возвращает пустой указатель, если она встречает признак конца файла.встречает признак конца файла.
Готово.
Интересно отметить, что хотя значение STLEN равно 10, похоже, программа не испытывает проблем при обработке строк ввода, длина которых значительно превышает этот предел. Дело в том, что в данной программе функция fgets() читает STLEN-1 (т.е. 9) символов за раз. Поэтому она начинает с чтения строки “Кстати го”, сохраняя ее как Кстати го\0. Затем fputs() отображает эту строку, но при этом не переходит на следующую строку вывода. Далее функция fgets() возобновляет чтение с того места, где она остановилась, и считывает “воря, фуп”, сохранив ее как воря, фун\0. Функция fputs() отображает эту строку в той же строке, в которой она находилась ранее. Затем fgets() возобновляет чтение ввода продолжая до тех пор, пока не останется прочитать только “()\n”; функция fgets() сохраняет строку() \n\0, функция fputs() отображает ее, а внутренний символ новой строки приводит к перемещению курсора на следующую строку.
Символьные строки и строковые функции 435
В системе используется буферизированный ввод-вывод. Это означает, что введенные данные сохраняются во временной памяти (буфере) до тех пор, пока не будет нажата клавиша . В результате этого к введенным данным добавляется символ новой строки, и вся строка передается функции fgets(). При выводе функция fputs() передает символы в другой буфер, и после отправки символа новой строки содержимое буфера передается дисплею.
Тот факт, что функция fgets() сохраняет символ новой строки, порождает проблему, но и предоставляет дополнительную возможность. Проблема заключается в том, что сохранение символа новой строки в виде части строки может быть нежелательным. Преимущество же в том, что присутствие или отсутствие символа новой строки в сохраненной строке может служить индикатором того, была ли прочитана вся строка. Если этого символа нет, можно принимать решение о том, что делать с оставшейся частью строки.
Во-первых, как избавиться от символа новой строки? Один из способов — его поиск в сохраненной строке и замена нулевым символом:
while (words[i] != '\n') // предполагается, что \n присутствует в words
i++;
words[i] = '\0';
Во-вторых, как быть, если в строке ввода по-прежнему остаются символы? Разумный подход на случай, если вся с трока не помещается в целевом массиве, предусматривает игнорирование не умещающейся части:
while (getchar() != '\n') // чтение без сохранения continue; // ввода, включая \n
В листинге 11.9 к этим базовым идеям добавляется дополнительная проверка, что дает в итоге код, который читает строки ввода, удаляет сохраненные символы новой строки, если таковые имеются, и отбрасывает часть строки, которая не умещается в выделенную область памяти.
Листинг 11.9. Программа fgets3. с
436 глава 11
Цикл
while (words[i] != '\n' && words[i] != '\n') i + +;
выполняет проход по строке до тех пор, пока не встретит символ новой строки или нулевой символ (в зависимости от того, что произойдет раньше). Если найденный символ является символом новой строки, то следующий за циклом оператор if заменяет его нулевым символом. В противном случае часть else отбрасывает остаток строки ввода. Ниже показаны результаты пробного запуска:
Введите строки (или пустую строку для выхода из программы):
Эта
Эта
программа, похоже,
программа
не желает принимать длинные строки.
не желает
Но, тем не менее, она не стопорится на
Но, тем н длинных строках.
длинных с
Готово.
Нулевой символ и нулевой указатель
В листинге 11.9 присутствуют и нулевой символ, и нулевой указатель. Концептуально эти две “нулевых” сущности отличаются друг от друга. Нулевой символ, или \0, является символом, применяемым для пометки конца строки С. Этот символ имеет код, равный нулю. Поскольку данный код не соответствует никакому другому символу, нулевой символ не может случайно появиться в какой-то другой части строки.
Читать дальшеИнтервал:
Закладка: