Брайан Керниган - Язык программирования Си. Издание 3-е, исправленное
- Название:Язык программирования Си. Издание 3-е, исправленное
- Автор:
- Жанр:
- Издательство:Невский Диалект
- Год:2001
- Город:Санкт-Петербург
- ISBN:0-13-110362-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Брайан Керниган - Язык программирования Си. Издание 3-е, исправленное краткое содержание
Книга широко известных авторов, разработчиков языка Си, переработанная и дополненная с учетом стандарта ANSI для языка Си, 2-е английское издание которой вышло в 1988 году, давно стала классикой для всех изучающих и/или использующих как Си, так и Си++. Русский перевод этой книги впервые был выпущен изд- вом "Финансы и статистика" в 1992 г. и с тех пор пользуется неизменным спросом читателей.
Для настоящего третьего русского издания перевод заново сверен с оригиналом, в него внесены некоторые поправки, учитывающие устоявшиеся за прошедшие годы изменения в терминологии, а так же учтены замечания, размещенные автором на странице http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html.
Для программистов, преподавателей и студентов.
Издание подготовлено при участии издательства "Финансы и статистика"
Язык программирования Си. Издание 3-е, исправленное - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
#include ‹stdio.h›
/* cat: конкатенация файлов, версия 2 */
main(int argc, char *argv[])
{
FILE *fp;
void filecopy(FILE *, FILE *);
char *prog = argv[0]; /* имя программы */
if (argc == 1) /* нет аргументов, копируется станд. ввод */
filecopy(stdin, stdout);
else
while (--argc › 0)
if ((fp = fopen(*++argv, "r")) == NULL) {
fprintf(stderr, "%s: не могу открыть файл %s\n", prog, *argv);
exit(1);
} else {
filecopy(fp, stdout);
fclose(fp);
}
if (ferror(stdout)) {
fprintf(stderr, "%s: ошибка записи в stdout\n", prog);
exit(2);
}
exit(0);
}
Программа сигнализирует об ошибках двумя способами. Первый - сообщение об ошибке с помощью fprintf посылается в stderr с тем, чтобы оно попало на экран, а не оказалось на конвейере или в другом файле вывода. Имя программы, хранящееся в argv[0] , мы включили в сообщение, чтобы в случаях, когда данная программа работает совместно с другими, был ясен источник ошибки.
Второй способ указать на ошибку - обратиться к библиотечной функции exit, завершающей работу программы. Аргумент функции exit доступен некоторому процессу, вызвавшему данный процесс. А следовательно, успешное или ошибочное завершение программы можно проконтролировать с помощью некоей программы, которая рассматривает эту программу в качестве подчиненного процесса. По общей договоренности возврат нуля сигнализирует о том, что работа прошла нормально, в то время как ненулевые значения обычно говорят об ошибках. Чтобы опорожнить буфера, накопившие информацию для всех открытых файлов вывода, функция exit вызывает fclose .
Инструкция return exp главной программы main эквивалентна обращению к функции exit(exp) . Последний вариант (с помощью exit ) имеет то преимущество, что он пригоден для выхода и из других функций, и, кроме того, слово exit легко обнаружить с помощью программы контекстного поиска, похожей на ту, которую мы рассматривали в главе 5. Функция ferrorвыдает ненулевое значение, если в файле fp была обнаружена ошибка.
int ferror(FILE *fp)
Хотя при выводе редко возникают ошибки, все же они встречаются (например, оказался переполненным диск); поэтому в программах широкого пользования они должны тщательно контролироваться.
Функция feof( FILE *fp ) aнaлoгичнa функции ferror ; oнa вoзвpaщaeт нeнулевое значение, если встретился конец указанного в аргументе файла.
int feof(FILE *fp);
В наших небольших иллюстративных программах мы не заботились о выдаче статуса выхода, т. е. выдаче некоторого числа, характеризующего состояние программы в момент завершения: работа закончилась нормально или прервана из-за ошибки? Если работа прервана в результате ошибки, то какой? Любая серьезная программа должна выдавать статус выхода.
7.7 Ввод-вывод строк
В стандартной библиотеке имеется программа ввода fgets, аналогичная программе getline , которой мы пользовались в предыдущих главах.
char *fgets(char *line, int maxline, FILE *fp)
Функция fgets читает следующую строку ввода (включая и символ новой строки) из файла fp в массив символов line , причем она может прочитать не более MAXLINE-1 символов. Переписанная строка дополняется символом '\0'. Обычно fgets возвращает line , а по исчерпании файла или в случае ошибки - NULL. (Наша getline возвращала длину строки, которой мы потом пользовались, и нуль в случае конца файла.)
Функция вывода fputsпишет строку (которая может и не заканчиваться символом новой строки) в файл.
int fputs(char *line, FILE *fp)
Эта функция возвращает EOF, если возникла ошибка, и неотрицательное значение в противном случае.
Библиотечные функции getsи putsподобны функциям fgets и fputs . Отличаются они тем, что оперируют только стандартными файлами stdin и stdout , и кроме того, gets выбрасывает последний символ '\n', a puts его добавляет.
Чтобы показать, что ничего особенного в функциях вроде fgets и fputs нет, мы приводим их здесь в том виде, в каком они существуют в стандартной библиотеке на нашей системе.
/* fgets: получает не более n символов из iop */
char *fgets(char *s, int n, FILE *iop) {
register int c;
register char *cs;
cs = s;
while (--n › 0 && (с = getc(iop)) != EOF)
if ((*cs++ = c) == '\n')
break;
*cs= '\0';
return (c == EOF && cs == s) ? NULL : s;
}
/* fputs: посылает строку s в файл iop */
int fputs(char *s, FILE *iop)
{
int c;
while (c = *s++)
putc(c, iop);
return ferror(iop) ? EOF : 0;
}
Стандарт определяет, что функция ferror возвращает в случае ошибки ненулевое значение; fputs в случае ошибки возвращает EOF, в противном случае - неотрицательное значение.
С помощью fgets легко реализовать нашу функцию getline :
/* getline: читает строку, возвращает ее длину */
int getline(char *line, int max)
{
if (fgets(line, max, stdin) == NULL)
return 0;
else
return strlen(line);
}
Упражнение 7.6. Напишите программу, сравнивающую два файла и печатающую первую строку, в которой они различаются.
Упражнение 7.7. Модифицируйте программу поиска по образцу из главы 5 таким образом, чтобы она брала текст из множества именованных файлов, а если имен файлов в аргументах нет, то из стандартного ввода. Будет ли печататься имя файла, в котором найдена подходящая строка?
Упражнение 7.8. Напишите программу, печатающую несколько файлов. Каждый файл должен начинаться с новой страницы, предваряться заголовком и иметь свою нумерацию страниц.
7.8 Другие библиотечные функции
В стандартной библиотеке представлен широкий спектр различных функций. Настоящий параграф содержит краткий обзор наиболее полезных из них. Более подробно эти и другие функции описаны в приложении B.
7.8.1 Операции со строками
Мы уже упоминали функции strlen , strcpy , strcat и strcmp , описание которых даны в ‹string.h›. Далее, до конца пункта, предполагается, что s и t имеют тип char * , c и n - тип int .
strcat(s,t)- приписывает t в конец s .
strncat(s,t,n)- приписывает n символов из t в конец s .
strcmp(s,t)- возвращает отрицательное число, нуль или положительное число для s ‹ t , s - t или s › t , соответственно.
strncmp(s,t,n)- делает то же, что и strcmp , но количество сравниваемых символов не может превышать n
strcpy(s,t)- копирует t в s .
strncpy(s,t,n)- копирует не более n символов из t в s .
strlen(s)- возвращает длину s .
Читать дальшеИнтервал:
Закладка: