Язык Си - руководство для начинающих
Шрифт:
if(fp = fopen(names[l], "r")) == 0)
printf(" Я не могу открыть %s.\n", names[l]);
else {
while(fseek(fp, offset++, 0) == 0)
{ putchar(getc(fp));
if(fseek(fp, -(offset + 3), 2) == 0)
putchar(getc(fp)); }
fclose(fp); }
} }
РИС. 15.2. Программа, чередующая печать в прямом и обратном направлениях.
Применение этой программы к
МоаилльоввоьллиаоМ
Наша программа печатает первый символ файла, затем последний, затем второй, затем предшествующий последнему и т.д. Мы только добавили вот эти строки в последнюю программу:
if(fseek(fp, -(offset + 3), 2) == 0)
putchar(getc(fp));
Код 2 в операторе предполагает, что мы будем считать позиции от конца файла. Знак минус означает счет в обратном направлении. +3 стоит здесь потому, что мы начинаем с последнего регулярного символа файла и пропускаем несколько символов "новая строка" и EOF в самом конце файла. (Точное значение этой корректировки зависит от типа системы. Наши файлы имеют в конце по два символа новой строки, за которыми следуют два EOF, поэтому мы как раз их и обходим.)
Таким образом, эта часть программы чередует печать в обратном направлении и печать в прямом направлении. Следует заметить, что в некоторых системах может не предусматриваться код 2 для fseek.
Теперь оставим на некоторое время файлы и перейдем к другому разделу библиотеки.
ПРОВЕРКА И ПРЕОБРАЗОВАНИЕ СИМВОЛОВ
Заголовочный файл ctype.h содержит несколько функций макроопределений, которые проверяют, к какому классу принадлежат символы. Функция isalpha(c), например, возвращает ненулевое значение (истина), если с является символом буквы, и нуль (ложь), если символ не является буквой. Таким образом,
isalpha('S') != 0, но isalpha('#') ==0
Ниже перечислены функции, чаще всего находящиеся в этом файле. В каждом случае функция возвращает ненулевое значение, если с принадлежит к опрашиваемому классу, и нуль в противном случае.
ФУНКЦИЯ | ПРОВЕРЯЕТ, ЯВЛЯЕТСЯ ЛИ С |
---|---|
isalpha(c) | буквой |
isdigit(c) | цифрой |
islower(c) | строчной буквой |
isspace(c) | пустым символом (пробел, табуляция или новая строка) |
isupper(c) | прописной буквой |
Ваша система может иметь дополнительные функции, такие как
ФУНКЦИЯ | ПРОВEРЯEТ, ЯВЛЯЕТСЯ ЛИ С |
---|---|
isalnum(c) | алфавитноцифровым (буква или цифра) |
isascii(c) | кодом ASCII (0-127) |
iscntrl(c) | управляющим символом |
ispunct(c) | знаком пунктуации |
Еще две функции выполняют преобразования
toupper(c) | преобразует с в прописную букву |
tolower(c) | преобразует с в строчную букву |
В некоторых системах преобразование выполняется только в случае, если символ находится в регистре (прописных или строчных букв), противоположном тому, с которого следует начинать. Однако надежнее предварительно проверить регистр.
Ниже (рис. 15.3.) дана программа, использующая некоторые из этих функций для преобразования всего файла в прописные или строчные буквы, по вашему желанию. Для получения небольшого разнообразия используем диалоговый подход, вместо того чтобы применять аргументы командной строки для снабжения программы информацией.
/* преобразование строчных букв в прописные и обратно */
#include <stdio.h>
#include <ctype.h> /* включает файл макроопределений */
#define UPPER 1
#define LOWER 0
main
{
int crit; /* для установки регистра прописных или строчных букв */
char file1[14], file2[14]; /* имена входного и выходного файлов */
crit = choose; /* выбирает прописные или строчные буквы */
getfiles(file1, file2); /* получаст имена файлов */
conv(file1, file2, crit); /* выполняет преобразование */
} choose
{ int ch;
printf("Программа преобразует весь файл в прописные буквы или \n");
printf(" в строчные буквы. Вводит U, если нужны прописные буквы\n");
printf(" или вводит L, если нужны строчные буквы. \n");
while((ch=getchar)!='U' && ch!='u' && ch!='L'
&& ch!='l')
printf(" Введите, пожайлуста, U или L.\n");
while(getchar!='\n')
; /* сбрасывает последний символ новой строки */
if(ch =='U' || ch =='u')
{ printf(" Все в порядке, есть регистр прописных букв.");
return(UPPER);
else
{ printf(" Все в порядке, есть регистр строчных букв.");
return(LOWER); } }
getfiles(namel, name2);
char *namel, name2;
{ printf(" Какой файл вы хотите преобразовать?\n");
gets(name1);
printf(" Это\" %s\" .\n", name1);
printf("Какое имя вы хотите выбрать для преобразуемого файла?\n");
while(strcmp(gets(name2), name1) == NULL)
printf(" Выберите другое имя.\n" );
printf(" Ваш выходной файл\" %s \".\n", name2);
} conv(name1, name2, crit);
char *name1, name2;
int crit;
{ int ch;
FILE *f1, *f2;
if((f1 = fopen(name1, "r" )) == NULL)