Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Форматный ввод - функция scanf
Осуществляющая ввод функция SCANF является аналогомPRINTF и позволяет проводить в обратном направлении многиеиз тех же самых преобразований. Функция SCANF(CONTROL, ARG1, ARG2,...) читает символы из стандартного ввода, интерпретирует их всоответствии с форматом, указанном в аргументе CONTROL, ипомещает результаты в остальные аргументы. Управляющий аргу-мент описывается ниже; другие аргументы, каждый из которыхдолжен быть указателем, определяют, куда следует поместитьсоответствующим образом преобразованный ввод. Управляющая строка обычно содержит спецификации преобра-зования, которые используются для непосредственной интерпре-тации входных последовательностей. Управляющая строка можетсодержать:- пробелы, табуляции или символы новой строки ("символы пус- тых промежутков"), которые игнорируются. - Обычные символы (не %), которые предполагаются совпадающи- ми со следующими отличными от символов пустых промежутков символами входного потока.- Спецификации преобразования, состоящие из символа %, нео- бязательного символа подавления присваивания *, необяза- тельного числа, задающего максимальную ширину поля и сим- вола преобразования. Спецификация преобразования управляет преобразованиемследующего поля ввода. нормально результат помещается в пе-ременную, которая указывается соответствующим аргументом.Если, однако, с помощью символа * указано подавление прис-ваивания, то это поле ввода просто пропускается и никакогоприсваивания не производится. Поле ввода определяется какстрока символов, которые отличны от символов простых проме-жутков; оно продолжается либо до следующего символа пустогопромежутка, либо пока не будет исчерпана ширина поля, еслиона указана. Отсюда следует, что при поиске нужного ей вво-да, функция 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.Доступ к файлам Все до сих пор написанные программы читали из стандарт-ного ввода и писали в стандартный вывод, относительно кото-рых мы предполагали, что они магическим образом предоставле-ны программе местной операционной системой. Следующим шагом в вопросе ввода-вывода является написа-ние программы, работающей с файлом, который не связан зара-нее с программой. одной из программ, которая явно демонстри-рует потребность в таких операциях, является 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); Первым аргументом функции 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(C) 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 вызы-вается автоматически для каждого открытого файла).
|
||||
Последнее изменение этой страницы: 2016-08-26; просмотров: 224; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.138.116.20 (0.005 с.) |