Первоначальная функция getchar( )извлекает U, но оставляет '\n'для следующего чтения строки. Функция gets(), входящая в getnames(), интерпретировала бы '\n'как пустую строку, поэтому мы использовали малый цикл while, чтобы избавиться от символа "новая строка". Действительно, простая getchar( ), сделала бы это, если бы пользователь непосредственно за Uнажимал бы [ ввод]. Но наша версия, кроме того, предусматривает возможность нажать на клавишу пробела несколько раз перед [ ввод].
В функции getnames( )для вас не должно быть сюрпризов. Учтите, что мы запрещаем пользователю применять одинаковые имена для выходного и входного файлов. Стандартная версия функции fopen( )не позволяет вам и читать и записывать один и тот же файл, если вы открыли его один раз.
Функция conv( )является функцией копирования с выполнением преобразования. Значение critиспользуется для определения требуемого преобразования. Работа выполняется простым условным оператором, таким как
ch = islower(ch) ? toupper(ch) : ch;
Он проверяет, является ли chстрочной буквой. Если да, то символ преобразуется в прописную букву. Если нет, остается как есть.
Макрофункции файла ctype.hпредоставляют удобные и полезные средства для программирования. Теперь давайте займемся некоторыми более сложными функциями преобразования.
ПРЕОБРАЗОВАНИЯ СИМВОЛЬНЫХ СТРОК: atoi( ), atof( )
Использование scanf( )для считывания цифровых значений не является самым надежным способом, поскольку scanf( )легко внести в заблуждение ошибками пользователей при вводе чисел с клавиатуры. Некоторые программисты предпочитают считывать даже числовые данные как символьные строки и преобразовывать строку в соответствующее числовое значение. Для этого используются функции atoi( )и atof( ). Первая преобразует строку в целое, вторая - в число с плавающей точкой. Вот (рис. 15.4) образец их использования:
/* включение atoi( ) */
#include
#define issign(c) (((с) == '-' || (с) == '+') ? (1) : (0))
#define SIZE 10
#define YES 1
#define NO 0
main( )
{
char ch;
static char number[SIZE];
int value;
int digit = YES;
int count = 0;
puts(" Введите, пожалуйста, целое.");
gets(number);
if(number[SIZE - 1] != '\0')
{ puts("Слишком много цифр; вы уничтожили меня.");
exit(1);
} while((ch = number[count]) !='0' && digit == YES)
if(!issign(ch) && iisdigit(ch) && !isspace(ch))
digit = NO;
if(digit == YES)
{ value = atoi(number);
printf(" Число было %d.\n" , value); }
else
printf(" Это не похоже на целое.");
}
РИС. 15.4. Программа использования atoi( ).
Мы предусмотрели проверку некоторых ошибок. Во-первых, следует посмотреть, умещается ли входная строка в предназначенном для нее массиве. Поскольку numberявляется статическим символьныммассивом, он инициализируется нулями. Если последний элемент массива не является нулем, значит что-то неверно, и программа прекращает работу. Здесь мы использовали библиотечную функцию exit( ), которая выводит нас из программы. Немного позже мы расскажем кратко об этой функции.
Затем посмотрим, не содержит ли строка что-нибудь кроме пробелов, цифр и алгебраических знаков. Функция отвергает такие строки, как "дерево" или "1.2Е2". Ее устраивает смесь, подобная "3 - 4 + 2", но atoi( )будет выполнять дальнейший отбор. Вспомним, что !является операцией отрицания, поэтому !isdigit(c)означает: "с не является цифрой". Строка
value = atoi(nuinbcr);
показывает, как используется функция atoi( ). Ее аргумент является указателем символьной строки; в этом случае мы применили имя массива number. Функция возвращает целое значение для такой строки. Таким образом, "1234" является строкой из четырех символов и переводится в 1234 - единое число типа int.
Функция atoi( )игнорирует ведущие пробелы, обрабатывает ведущий алгебраический знак, если он есть, и обрабатывает цифры вплоть до первого символа, нс являющегося цифрой. Поэтому наш пример "3 - 4 + 2" был бы превращен в значение 3. Посмотрите "Вопросы" в конце главы для возможного применения этой функции.
Функция atof( )выполняет подобные действия для чисел с плавающей точкой. Она возвращает тип double, поэтому должна быть описана как doubleв использующей ее программе.
Простые версии atof( )будут обрабатывать числа вида 10.2, 46 и - 124.26. Более мощные версии преобразуют также экспоненциальную запись, т. е. числа, подобные 1.25Е - 13.
Читать дальше