46170 (588390), страница 16

Файл №588390 46170 (Язык С) 16 страница46170 (588390) страница 162016-07-29СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 16)

Спецификации преобразования, состоящие из символа %, необязательного символа подавления присваивания *, необязательного числа, задающего максимальную ширину поля и символа преобразования.

Спецификация преобразования управляет преобразованием следующего поля ввода. нормально результат помещается в переменную, которая указывается соответствующим аргументом.

Если, однако , с помощью символа * указано подавление присваивания, то это поле ввода просто пропускается и никакого присваивания не производится. Поле ввода определяется как строка символов, которые отличны от символов простых промежутков; оно продолжается либо до следующего символа пустого промежутка, либо пока не будет исчерпана ширина поля, если она указана. Отсюда следует, что при поиске нужного ей ввода, функция SCANF будет пересекать границы строк, поскольку символ новой строки входит в число пустых промежутков.

Символ преобразования определяет интерпретацию поля ввода; согласно требованиям основанной на вызове по значению семантики языка “с” соответствующий аргумент должен быть указателем. Допускаются следующие символы преобразования: D - на вводе ожидается десятичное целое; соответствующий аргумент должен быть указателем на целое.

O - На вводе ожидается восьмеричное целое (с лидирующим нулем или без него); соответствующий аргумент должен быть указателем на целое.

X - На вводе ожидается шестнадцатеричное целое (с лидирующими 0X или без них); соответствующий аргумент должен быть указателем на целое.

H - На вводе ожидается целое типа SHORT; соответсвующий аргумент должен быть указателем на целое типа SHORT.

C - Ожидается отдельный символ; соответствующий аргумент должен быть указателем на символы; следующий вводимый символ помещается в указанное место. Обычный пропуск символов пустых промежутков в этом случае подавляется; для чтения следующего символа, который не является символом пустого промежутка, пользуйтесь спецификацией преобразования %1S.

S - Ожидается символьная строка; соответствующий аргумент должен быть указателем символов, который указывает на массив символов, который достаточно велик для принятия строки и добавляемого в конце символа \0.

F - Ожидается число с плавающей точкой; соответствующий аргумент должен быть указателем на переменную типа FLOAT.

Е - символ преобразования E является синонимом для F. Формат ввода переменной типа FLOAT включает необязательный знак, строку цифр, возможно содержащую десятичную точку и необязательное поле экспоненты, состоящее из буквы E, за которой следует целое, возможно имеющее знак.

Перед символами преобразования D, O и X может стоять L, которая означает , что в списке аргументов должен находиться указатель на переменную типа LONG, а не типа INT. Аналогично, буква L может стоять перед символами преобразования E или F, говоря о том, что в списке аргументов должен находиться указатель на переменную типа DOUBLE, а не типа FLOAT.

Например, обращение INT I;

FLOAT X;

CHAR NAME[50];

SCANF(“&D %F %S”, &I, &X, NAME);

со строкой на вводе 25 54.32E-1 THOMPSON приводит к присваиванию I значения 25,X - значения 5.432 и NAME - строки “THOMPSON”, надлежащим образом законченной символом \ 0. эти три поля ввода можно разделить столькими пробелами, табуляциями и символами новых строк, сколько вы пожелаете. Обращение

INT I;

FLOAT X;

CHAR NAME[50];

SCANF(“%2D %F %*D %2S”, &I, &X, NAME);

с вводом 56789 0123 45A72 присвоит I значение 56, X - 789.0, пропустит 0123 и поместит в NAME строку “45”. при следующем обращении к любой процедуре ввода рассмотрение начнется с буквы A. В этих двух примерах NAME является указателем и, следовательно, перед ним не нужно помещать знак &.

В качестве другого примера перепишем теперь элементарный калькулятор из главы 4, используя для преобразования ввода функцию SCANF: #INCLUDE MAIN() /* RUDIMENTARY DESK CALCULATOR */

\( DOUBLE SUM, V;

SUM =0;

WHILE (SCANF(“%LF”, &V) !=EOF) PRINTF(“\T%.2F\N”, SUM += V);

\)

выполнение функции SCANF заканчивается либо тогда, когда она исчерпывает свою управляющую строку, либо когда некоторый элемент ввода не совпадает с управляющей спецификацией. В качестве своего значения она возвращает число правильно совпадающих и присвоенных элементов ввода. Это число может быть

использовано для определения количества найденных элементов ввода. при выходе на конец файла возвращается EOF; подчеркнем, что это значение отлично от 0, что следующий вводимый символ не удовлетворяет первой спецификации в управляющей строке. При следующем обращении к SCANF поиск возобновляется непосредственно за последним введенным символом.

Заключительное предостережение: аргументы функции SCANF должны быть указателями. Несомненно наиболее распространенная ошибка состоит в написании

SCANF(“%D”, N);

вместо SCANF(“%D”, &N);

7.5. Форматное преобразование в памяти

От функции SCANF и PRINTF происходят функции SSCANF и SPRINTF, которые осуществляют аналогичные преобразования, но оперируют со строкой, а не с файлом. Обращения к этим функциям имеют вид:

SPRINTF(STRING, CONTROL, ARG1, ARG2, ...) SSCANF(STRING, CONTROL, ARG1, ARG2, ...) Как и раньше , функция SPRINTF преобразует свои аргументы ARG1, ARG2 и т.д. В соответствии с форматом, указанным в CONTROL, но помещает результаты в STRING, а не в стандартный вывод. KОнечно, строка STRING должна быть достаточно велика, чтобы принять результат. Например, если NAME - это символьный массив, а N - целое, то

SPRINTF(NAME, “TEMP%D”, N);

создает в NAME строку вида TEMPNNN, где NNN - значение N.

Функция SSCANF выполняет обратные преобразования - она просматривает строку STRING в соответствии с форматом в аргументе CONTROL и помещает результирующие значения в аргументы ARG1, ARG2 и т.д.эти аргументы должны быть указателями. В результате обращения

SSCANF(NAME, “TEMP%D”, &N);

переменная N получает значение строки цифр, следующих за TEMP в NAME.

Упражнение 7-2.

Перепишите настольный калькулятор из главы 4, используя для ввода и преобразования чисел SCANF и/или SSCANF.

160

7.6. Доступ к файлам Все до сих пор написанные программы читали из стандартного ввода и писали в стандартный вывод, относительно которых мы предполагали, что они магическим образом предоставлены программе местной операционной системой.

Следующим шагом в вопросе ввода-вывода является написание программы, работающей с файлом, который не связан заранее с программой. одной из программ, которая явно демонстрирует потребность в таких операциях, является CAT, которая объединяет набор из нескольких именованных файлов в стандартный вывод. Программа CAT используется для вывода файлов на терминал и в качестве универсального сборщика ввода для программ, которые не имеют возможности обращаться к файлам по имени. Например, команда

CAT X.C.Y.C печатает содержимое файлов X.C и Y.C в стандартный вывод.

Вопрос состоит в том, как организовать чтение из именованных файлов, т.е., как связать внешние имена, которыми мыслит пользователь, с фактически читающими данные операторами.

Эти правила просты. Прежде чем можно считывать из некоторого файла или записывать в него, этот файл должен быть открыт с помощью функции FOPEN из стандартной библиотеки.

функция FOPEN берет внешнее имя (подобное X.C или Y.C), проводит некоторые обслуживающие действия и переговоры с операционной системой (детали которых не должны нас касаться) и возвращает внутреннее имя, которое должно использоваться при последующих чтениях из файла или записях в него.

Это внутреннее имя, называемое “указателем файла”, фактически является указателем структуры, которая содержит информацию о файле, такую как место размещения буфера, текущая позиция символа в буфере, происходит ли чтение из файла или запись в него и тому подобное. Пользователи не обязаны знать эти детали, потому что среди определений для стандартного ввода-вывода, получаемых из файла STDIO.H, содержится определение структуры с именем FILE. Единственное необходимое для указателя файла описание демонстрируется примером:

FILE *FOPEN(), *FP;

Здесь говорится, что FP является указателем на FILE и FOPEN возвращает указатель на FILE. Oбратите внимание, что FILE является именем типа, подобным INT, а не ярлыку структуры; это реализовано как TYPEDEF. (Подробности того, как все это работает на системе UNIX, приведены в главе 8).

Фактическое обращение к функции FOPEN в программе имеет вид: FP=FOPEN(NAME,MODE);

161

Первым аргументом функции FOPEN является “имя” файла, которое задается в виде символьной строки. Второй аргумент MODE (“режим”) также является символьной строкой, которая указывает, как этот файл будет использоваться. Допустимыми режимами являются: чтение (“R”), запись (“W”) и добавление (“A”).

Если вы откроете файл, который еще не сущетвует, для записи или добавления, то такой файл будет создан (если это возможно). Открытие существующего файла на запись приводит к отбрасыванию его старого содержимого. Попытка чтения несуществующего файла является ощибкой. Ошибки могут быть обусловлены и другими причинами (например, попыткой чтения из файла, не имея на то разрешения). При наличии какой-либо ошибки функция возвращает нулевое значение указателя NULL (которое для удобства также определяется в файле STDIO.H).

Другой необходимой вещью является способ чтения или записи, если файл уже открыт. Здесь имеется несколько возможностей, из которых GETC и PUTC являются простейшими.функция GETC возвращает следующий символ из файла; ей необходим указатель файла, чтобы знать, из какого файла читать. Таким образом, C=GETC(FP) помещает в “C” следующий символ из файла, указанного посредством FP, и EOF, если достигнут конец файла.

Функция PUTC, являющаяся обращением к функции GETC, PUTC(C,FP) помещает символ “C” в файл FP и возвращает “C”. Подобно фун-кциям GETCHAR и PUTCHAR, GETC и PUTC могут быть макросами, а не функциями.

При запуске программы автоматически открываются три файла, которые снабжены определенными указателями файлов. Этими файлами являются стандартный ввод, стандартный вывод и стандартный вывод ошибок; соответствующие указатели файлов называются STDIN, STDOUT и STDERR. Обычно все эти указатели связаны с терминалом, но STDIN и STDOUT могут быть перенаправлены на файлы или в поток (PIPE), как описывалось в разделе 7.2.

Функции GETCHAR и PUTCHAR могут быть определены в терминалах GETC, PUTC, STDIN и STDOUT следующим образом: #DEFINE GETCHAR() GETC(STDIN) #DEFINE PUTCHAR© PUTC(C, STDOUT) При работе с файлами для форматного ввода и вывода можно использовать функции FSCANF и FPRINTF. Они идентичны функциям SCANF и PRINTF, за исключением того, что первым аргументом является указатель файла, определяющий тот файл, который будет читаться или куда будет вестись запись; управляющая строка будет вторым аргументом.

Покончив с предварительными замечаниями, мы теперь в состоянии написать программу CAT для конкатенации файлов.

Используемая здесь основная схема оказывается удобной во многих программах: если имеются аргументы в командной строке, то они обрабатываются последовательно. Если такие аргументы отсутствуют, то обрабатывается стандартный ввод. Это позволяет использовать программу как самостоятельно, так и как часть большей задачи.

#INCLUDE MAIN(ARGC, ARGV) /*CAT: CONCATENATE FILES*/ INT ARGC;

CHAR *ARGV[];

\( FILE *FP, *FOPEN();

IF(ARGC==1) /*NO ARGS; COPY STANDARD INPUT*/ FILECOPY(STDIN);

ELSE WHILE (--ARGC > 0) IF ((FP=FOPEN(*++ARGV,”R”))==NULL) \( PRINTF(“CAT:CAN'T OPEN %\N”,*ARGV);

BREAK;

\) ELSE \( FILECOPY(FP);

FCLOSE(FP);

\)

\) FILECOPY(FP) /*COPY FILE FP TO STANDARD OUTPUT*/ FILE *FP;

\( INT C;

WHILE ((C=GETC(FP)) !=EOF) PUTC(C, STDOUT);

\)

Указатели файлов STDIN и STDOUT заранее определены в библиотеке ввода-вывода как стандартный ввод и стандартный вывод;

они могут быть использованы в любом месте, где можно использовать объект типа FILE*.они однако являются константами, а не переменными, так что не пытайтесь им что-либо присваивать.

Функция FCLOSE является обратной по отношению к FOPEN;

она разрывает связь между указателем файла и внешним именем, установленную функцией FOPEN, и высвобождает указатель файла для другого файла.большинство операционных систем имеют некоторые ограничения на число одновременно открытых файлов, которыми может распоряжаться программа. Поэтому, то как мы поступили в CAT, освободив не нужные нам более объекты, является хорошей идеей. Имеется и другая причина для применения функции FCLOSE к выходному файлу - она вызывает выдачу информации из буфера, в котором PUTC собирает вывод. (При нормальном завершении работы программы функция FCLOSE вызывается автоматически для каждого открытого файла).

163

7.7. Обработка ошибок - STDERR и EXIT Обработка ошибок в CAT неидеальна. Неудобство заключается в том, что если один из файлов по некоторой причине оказывается недоступным, диагностическое сообщение об этом печатается в конце объединенного вывода. Это приемлемо, если вывод поступает на терминал, но не годится, если вывод поступает в некоторый файл или через поточный (PIPELINE) механизм в другую программу.

Чтобы лучше обрабатывать такую ситуацию, к программе точно таким же образом, как STDIN и STDOUT, присоединяется второй выходной файл, называемый STDERR. Если это вообще возможно, вывод, записанный в файле STDERR, появляется на терминале пользователя, даже если стандартный вывод направляется в другое место.

Давайте переделаем программу CAT таким образом, чтобы сообщения об ошибках писались в стандартный файл ошибок.

“INCLUDE MAIN(ARGC,ARGV) /*CAT: CONCATENATE FILES*/ INT ARGC;

CHAR *ARGV[];

Характеристики

Тип файла
Документ
Размер
1,37 Mb
Материал
Учебное заведение
Неизвестно

Список файлов ВКР

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7021
Авторов
на СтудИзбе
260
Средний доход
с одного платного файла
Обучение Подробнее