Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЯЗЫК СИ_РУКОВОДСТВО ПРОГРАММИСТА.doc
Скачиваний:
12
Добавлен:
18.08.2019
Размер:
438.27 Кб
Скачать

CCCCCCCC III III

CCCCCCCCCC III III

CCC CCC III III

CCC CC III III

CCC III IIII

CCC III IIIII

CCC III IIIIII

CCC III III III

CCC III III III

CCC IIIIII III

CCC IIIII III

CCC CC IIII III

CCC CCC III III

CCCCCCCCCC III III

CCCCCCCC III III

ЛГУ

СОДЕРЖАНИЕ

1. Язык СИ. Руководство программиста. Функции стандартной библиотеки........................................................ 2

1.1. Форматный ввод/вывод........................................ 8

1.2. Нефайловая работа с терминалом..............................13

1.3. Управление распределением динамической памяти...............14

1.4. Работа со строками и символами..............................16

1.5. Средства отладки............................................23

2. Библиотека математических функций CMLIB.OBJ.......................26

3. Графбиблиотека CGLIB.OBJ..........................................28

4. Библиотека системных функций ОС RT11 CRLIB.OBJ....................30

5. Язык СИ. Руководство оператора....................................32

5.1. Стадии подготовки программы.................................32

5.2. Проблемы промежуточных файлов...............................34

5.3. Эмуляция EIS................................................35

5.4. Вычисление с плавающей запятой..............................35

5.5. Инициализация FPU...........................................36

5.6. Форматный вывод чисел с плавающей запятой...................36

5.7. Оптимизация.................................................36

5.8. Компоновка..................................................37

5.9. Создание автономных программ................................37

5.10.Сообщения оператору.........................................38

6. Дополнения к комплекту СИ.........................................39

6.1. Ввод и обработка командной строки...........................41

6.2. Управление стартовыми действиями............................42

7. Пакет работы с терминалом.........................................43

7.1. Обновление экрана...........................................43

7.2. Запуск......................................................45

7.3. Вывод.......................................................45

7.4. Ввод........................................................45

7.5. Завершение работы...........................................45

7.6. Оптимизация движения курсора................................46

8. Графический редактор..............................................52

9. Краткое описание компилятора СИ фирмы DEC.........................53

10.Перечень ошибок...................................................54

1. ЯЗЫК СИ. РУКОВОДСТВО ПРОГРАММИСТА.

ФУНКЦИИ СТАНДАРТНОЙ БИБЛИОТЕКИ

Многие обьекты, которые встречаются в настоящем описании, используются, в основном, через указатели на них, поэтому часто указатели на обьект при описании отождествляются с самим обьектом. Файл, например, определяется дескриптором файла - структурой типа "FILE" (тип описан в файле "STDIO.H"), однако, т.к. на файл ссылаются при помощи указателя на его дескриптор, этот указатель при описании отождествляют с файлом. Это, как правило, не создает неоднозначностей.

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

FILE *iop; /* указатель на дескриптор файла */

,то выражение "файл iop" в дальнейшем описании будет означать "файл,

на дескриптор которого указывает iop". В файле "STDIO.H" определены

символы "NULL" (0) и EOF (-1). Эти символы определяют выделенные

значения, возвращаемые некоторыми функциям для информации об ошибке

или нестандартном событии.

При старте программы, написанной на "СИ", автоматически открываются (если это явно не подавлено) три файла:

stdin - файл стандартного ввода

stdout - Файл стандартного вывода

stderr - файл стандартного вывода ошибок

эти файлы по умолчанию связываются с терминалом, однако

соответствующими аргументами в командной строке файлы "STDIN" и

"STDOUT" могут быть перенаправлены на другие устройства и файлы (см.

"руководство пограммиста. библиотеки. Исполняющая система").

fopen

char *name; /* спецификация файла */

char *mode; /* способ открытия */

file *

fopen(name,mode);

открывает новый или существуюший файл. Спецификация файла задается

в строке "name" в формате CSI. Если в имени файла отсутствует имя

устройства, то предполагается "DK:", если отсутствует длина, то

предполагается "[0]" (для файлов, открываемых на чтение, длина

игнорируется). Если устройство нефайловое,например "TT:", "LP:" и

т.п., то можно опустить имя и тип файла. Отметим, что пустая

спецификация файла не расширится в "DK:", а будет зафиксирована

ошибка. примеры допустимых имен:

RK1:MAMA.FOR

RK1:MAMA.FOR

AMA.FOR

DX0:PROG10.C[12]

KISS.TXT

LP:

способ открытия файлов определяется аргументом "mode", который

представляет способ открытия файлов определяется аргументом "mode",

который представляет собой строку, содержащую некоторую комбинацию

сдедующих ключей:

R - открытие существующего файла на ввод.

W - открытие нового файла на вывод.

N - открытие файла в "двоичном" (не символьном) режиме:

в ОС "UNIX" в символьных файлах строка ограничивается символом '\N'

(<ПС>), символ '\R' (<ВК>) отсутствует.

В ОС RT11 ограничителем строки является комбинация "\R\N". т.к. наиболее часто используется ввод и вывод именно символьных файлов, для совместимости по умолчанию файл открывается таким образом, что

при вводе '\R' выбрасываются, а при выводе вставляются перед '\N'. однако, при чтении не символьного (двоичного) файла этот режим может приводить к ошибкам, и следует открывать файл с ключом 'N'.

U - производить посимвольный вывод

имеет смысл только для файлов, открытых на терминал (в противном случае игнорируется); обычно вывод на терминал выполняется с буферизацией и по .PRINT, при открытии же файла с ключом 'U' вывод будет выполняться посимвольно (без буферизации) по .TTYOUT (ввод с терминала всегда осуществляется по .TTYIN, и для посимвольного ввода необходимо воспользоваться функцией $ttymode()). Заметим, что stderr открыт с ключом 'U'.

D - позволяет выполнить нефайловое открытие файлового устройства: без этого ключа при попытке выполнить "fopen("RK1:","R");" мы получим ошибку, однако "fopen("RK1:","RD");" выполнится без ошибки. Нефайловое открытие устройства с файловой структурой полезно при создании программ, работающих непосредственно с каталогом (примеры - fwild() и rdir() из CRLIB) или программ, предназначенных для работы с дисками, на котрых отсутствует файловая система ОС RT11. Ошибка будет возникать, если ключ 'D' используется с ключом 'W', а также если устройство, к которому происходит обращение, имеет нестандартную файловую структуру (например "MT:").

Один из ключей 'R' или 'W' должен присутствовать (но не оба!!!), остальные ключи могут присутствовать или отсутствовать.

При удачном открытии fopen() резервирует (по malloc()) область для дескриптора файла и буфера (около 530. байт) и возвращает указатель на нее. При неудачном открытии fopen() возвращает NULL (0).

При открытии на чтение существующего файла в глобальную переменную "$$FLEN" заносится его длина (0 для устройств с нефайловой структурой).

Если драйвер устройства, указанного при открытии файла, не загружен, то fopen() загружает его, резервируя память по malloc(). Драйвер остается загруженным, а память под него зарезервированной до окончания задачи.

Один и тот же файл не может быть одновременно открыт на запись и на чтение. При работе с временными файлами после записи файл должен быть закрыт, а потом открыт снова, уже на чтение. Можно использовать также функцию rewind(), которая для файлов, открытых на запись, делает именно это.

Ограниченные возможности непосредственного доступа к записям в файле предоставляются функциями ftell() - fseek().

Приведем пример использования функции fopen() на примере простой программы, копирующей поизвольный файл "a.txt" в файл "b.txt".

#include <stdio.h>

char inname[]="A.TXT"; /* имя входного файла */

char outname[]="B.TXT"; /* имя выходного файла */

main()

register c;

file *inf; /* файл ввода */

file *outf; /* файл вывода */

if((inf=fopen(inname,"RN")) == null)

error("ошибка открытия файла ввода \"%s\",

inname);

if((outf=fopen(outname,"WN")) == null)

error("ошибка открытия файла вывода \"%s\",

outfname);

/* копирование */

while((c = getc(inf)) != eof) putc(c);

freopen

char *name; /* имя файла */

char *mode; /* способ открытия */

file *iop;

file *

freopen(name,mode,iop);

freopen() аналогична fopen(), но использует уже существующий дескриптор файла, на который указывает iop. Файл, ранее связанный с iop, закрывается. Если произошла ошибка открытия файла, дескриптор файла освобождается. Ошибки закрытия файла игнорируются.

freopen() нормально возвращает "iop", и NULL при ошибке.

fclose

file *iop; /* указатель на дескриптор файла */

fclose(iop);

Закрывает файл iop и освобождает память, занятую под дескриптор. возвращает 0, если ошибок нет, и -1 при ошибке. Заметим, что stderr закрыть нельзя. Последний блок файла, открытого для записи на устройстве с произвольным доступом (диске) дополняется нулями.

fpclose

file *iop;

fpclose(iop);

Функция fpclose() аналогична fclose(), однако если файл был открыт на вывод и при его закрытии произошла ошибка, то файл не закрывается (т.е. теряется).

fpurge

file *iop;

fpurge(iop);

Освобождает канал, не закрывая файла, и освобождает память, занятую под дескриптор. Если файл был открыт на вывод, он теряется.

getchar, getc

file *iop;

getchar();

getc(iop);

getchar() вводит один символ из стандартного файла ввода (stdin). getc() вводит один символ из файла iop. Возвращают EOF (-1) при ошибке или при конце файла. Если файл ввода открыт без указания ключа 'N' (по умолчанию stdin открывается именно так), то при вводе символ '\R' (<BK>) будет игнорироваться.

putchar, putc

char c;

file *iop;

putchar(c);

putc(c,iop);

putchar() выводит один символ в стандартный файл вывода (stdout).

putc() выводит один символ в файл iop. Нормально возвращают значение

символа и eof при ошибке. Если выходной файл открыт без указания

ключа 'n', то при выводе символа '\N' (<ПС>) перед ним будет

добавлен символ '\R' (<ВК>).

ungetc

char c;

file *iop;

ungetc(c,iop);

возвращает один символ в указанный файл ввода (символ сохраняется в

специально отведенном элементе дескриптора файла). При попытке

возвратить в файл более одного символа происходит аварийное

Ппрерывание программы по инструкции BPT.

getw

file *iop;

getw(iop);

читает из файла iop два байта и возвращает их как одно 16-ти

разрядное слово. Никакого выравнивания не производится. Если вы

читаете двоичный файл, его необходимо открыть с ключом 'N'.

Используйте feof() и ferror() для проверок на конец файла и ошибки.

putw

int word;

file *iop;

putw(word,iop);

записывает слово word в файл iop побайтно (сначала младший байт),

никакого выравнивания не производится. Файл рекомендуется открывать

с ключом 'N', иначе возможно искажение информации и перекосы.

Возвращает 0 при удачном завершении и EOF при ошибке.

gets, fgets, fgetss

char *buffer;

int maxbytes;

file *iop;

char *

gets(buffer);

char *

fgets(buffer,maxbytes,iop);

char *

fgets(buffer,maxbytes,iop);

gets() - вводит строку в буфер "buffer" из стандартного файла

ввода. Ограничение на длину вводимой строки отсутствует.

Строкой считается последовательность символов,

заканчивающаяся символом '\N'. Символ '\N' заменяется в

буфере на '\0'.

fgets() - вводит строку из файла iop в буфер "buffer". Если строка

длиннее maxbytes-1 байт, то строка обрезается и '\N'

добавляется. Строка в буфере всегда заканчивается сим­волами '\N' '\0'.

fgetss() - делает то же, что и fgets(), однако '\N' в буфер не заносится, строка ограничивается нулем. Это совместимо с gets() и fget(), но не совпадает со стандартами библиотеки ОС UNIX.

Нормально возвращают buffer, при ошибке или конце файла возвращают NULL.

puts, fputs, fputss

char *s;

file *iop;

puts(s);

fputs(s,iop);

fputss(s,iop);

puts() - записывает строку s в стандартный файл вывода. В конец строки добавляется '\N'.

fputs() - записывает строку s в указаннный файл. '\N' в конец строки

не добавляется.

fputss() - записывает строку s в указанный файл. В конец строки

добавляется '\N'. Функции возвращают EOF в случае ошибки

или конца файла.

fread

struct object *op;

int nitem;

file *iop;

fread(op, sizeof(*op), nitem, iop);

вводит указанное (nitem) число двоичных записей (записи неформатные,

функции fread() - fwrite() не имеют никакого отношения к функциям

fget() - fput()) из указанного файла в буфер, на который указывает

op. Длина записи указывается во втором аргументе (в примере - как

sizeof(*op)). Возвращает число фактически введенных записей. Оно

может быть нулем, если при вводе возникли ошибки или был достигнут

конец файла.

fwrite

struct object *op;

int nitem;

file *iop;

fread(op, sizeof(*op), nitem, iop);

выводит "nitem" двоичных записей в файл iop из буфера, на который

указывает op. Длина записи указывается во втором аргументе (в

примере - как sizeof(*op)). Возвращает число фактически выведенных

записей. Оно может быть нулем, если при записи возникли ошибки или

был достигнут конец файла.

fget

char *buffer;

int maxbytes;

file *iop;

fget(buffer, maxbytes, iop);

вводит форматную запись (запись в формате RSX, каждой записи (строке)

предшествует счетчик байт, занимающий 2 байта) из файла iop в

"buffer". Если длина записи превосходит maxbytes, то в буфер будет

занесено maxbytes байт, остальные байты этой записи будут потеряны.

В ОС RT11 функцию fget() можно использовать для чтения файлов, записанных при помощи функции fput(), и для перекодирования файлов, записанных в RSX. Файл должен быть открыт с ключом 'N'.

Возвращает число фактически прочитанных байт (может быть больше maxbytes). Используйте feof() для проверки на конец файла.

fput

char *buffer;

int nbytes;

file *iop;

fput(buffer,nbytes,iop);

выводит nbytes байт из буфера "buffer" в файл "iop" в виде форматной

двоичной записи (в формате RSX). Файл должен быть открыт с ключом

'N'. Читать эти записи можно только при помощи функции fget(). Всегда

возвращает nbytes. Используйте ferror() после fput() для проверки на

ошибки записи.

fseek

file *iop;

long offset;

int param;

fseek(iop,offset,param);

перемещает указатель текущей позиции чтения файла iop в позицию,

указанную в offset. Возвращает 0 при нормальном завершении, eof при

ошибке. При нормальном завершении сбрасываются флаги ошибки и конца

файла и символ, возвращенный по ungetc(). Устройство должно

допускать непосредственный доступ (иначе ошибка),

param должен быть равен 0 (иначе ошибка).

param введен для совместимости с ОС UNIX, где 0 означает абсолютное позиционирование - в ОС UNIX возможно и относительное.

offset должен быть получен от функции ftell(). В ОС UNIX при param=0 offset является номером байта от начала файла. В данной реализации это не так: offset в младшем слове содержит номер блока файла, а в старшем слове - номер байта в блоке.

fseek не возвращает кода ошибки через $$ferr.

ftell

file *iop;

long

ftell(iop);

возвращает текущее положение указателя позиции чтения/записи файла

iop. Это положение (при чтении) может быть восстановлено вызовом

fseek().

rewind

file *iop;

rewind(iop);

производит установку указателя чтения/записи файла на начало файла.

Возвращает 0 при нормальном завершении, EOF при ошибке. Если файл открыт на запись, то файл закрывается и открывается на чтение. Если при закрытии файла или при открытии возникает ошибка, то файл не открывается и дескриптор файла освобождается.

delete

char *filename;

delete(filename);

стирает файл, имя которого (в ASCII) указано в строке filename. Если драйвер устройства, на которм находится указанный файл, не загружен, delete() загружает его, резервируя память по malloc(), и выгружает драйвер и освобождет память после завершения операции. Возвращает 1 йпри успешном завершении и 0 при ошибке. В последнем случае код

ошибки находится в $$ferr и errno.

fmkdl

file *iop;

fmkdl(iop);

закрывает и стирает указанный файл. Возвращает 0 при успешном завершении, -1 при ошибке. fmkdl() устарела и несколько некорректна. используйте delete().

fgchan

fgchan();

находит свободный канал ввода/вывода, помечает его в таблицах исполняющей системы языка "СИ" как занятый и возвращает его номер (>=0). Возвращает -1, если свободных каналов нет.

frchan

int chan;

frchan(chan);

освобождает канал, полученный по fgetc(), помечая его в таблицах исполняющей системы языка "СИ" как свободный. Возвращает:

0 - нормальное завершение

1 - недопустимый номер канала

2 - канал не закрыт

3 - канал занят не по fgchan()

fgetname

file *iop;

char *buffer;

fgetname(iop,buffer);

заносит в буфер "buffer" имя файла iop в ASCII (хранится в дескрипторе).

feof

file *iop;

feof(iop);

возвращает 1, если в файле iop достигнут конец, и 0 в противном случае.

ferror

file *iop;

ferror(iop);

возвращает 1, если при работе с файлом iop была зафиксирована ошибка, и 0 в противном случае.

flun

file *iop;

flun(iop);

возвращает номер канала ввода/вывода, который связан с файлом iop.

frec

file *iop;

frec(iop);

возвращает 1, если файл iop записеориентированный, и 0 в противном случае. Записеориентированными считаются устойства с нефайловой структурой (не включая терминал), например "PC:", "LP:" и т.п.

ftty

file *iop;

ftty(iop);

возвращает 1, если файл iop связан с терминалом, и 0 в противном случае.

gettty

char *buffer;

gettty(buffer);

заносит в буфер "buffer" строку имени устройства управляющего терминала. Это актуально в ОС UNIX и RSX, в ОС RT11 gettty() всегда возвращает "TT:". Присутствует для совместимости.

fclear

file *iop;

очищает (сбрасывает) флаг ошибки и флаг EOF в дескрипторе файла iop. Это может быть полезно при работе с терминалом.

1.1. Форматный ввод/вывод

printf, fprintf, sprintf

char *format;

printf(format , arg ...)

char *format;

file *iop;

fprintf(iop, format , arg ...)

char *format;

char *buffer;

sprintf(buffer, format , arg ...)

осуществляют форматные преобразования и вывод указанной информации. printf() помещает вывод в стандартный файл вывода (stdout), fprintf() помещает вывод в указанный файл iop, sprintf() помещает вывод в строку buffer (при этом последним символом будет '\0'). Каждая из этих функций преобразовывает, форматирует и печатает свои аргументы ("arg", аргументы начиная со второго для printf()) под управлением аргумента "format" (первый аргумент для printf())."format" представляет собой символьную строку, содержащую два типа обьектов: обыкновенные символы, которые просто копируются в выходной поток, и спецификации преобразования, которые управляют преобразованием и печатью очередного аргумента printf().

Каждая спецификация преобразования начинается с символа "%". Вслед за ним могут идти:

*необязательный знак "-", который указывает на необходимость левого выравнивания информации в указанном поле (по умолчанию выполняется правое выравнивание);

*необязательная цифровая строка, определяющая ширину поля: если преобразованная величина имеет меньше символов,чем ширина поля, то оно будет заполнено пробелами слева (или справа, если задан указатель левого выравнивания); если ширина поля начинается с нуля, будет произведено заполнение нулями, а не пробелами;

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

*необязательная цифровая строка, определяющая точность (т.е. число цифр после десятичной точки для спецификаций формата 'e' и 'f', или максимальное число символов печатаемой строки для спецификации формата 's');

*символ l (малое или большое),указывающий, что следующие за ним спецификации формата d, o, x или u соответствуют целому числу с двойной точностью. Если после 'l' не присутствуют указанные спецификации формата,то такая конструкция обрабатывается как формат 'u', т.е. нормальное целое без знака;

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

Ниже приведены символы типов преобразования и обьяснение их смысла:

d, u, o, x

целое число "arg" преобразовывается соответственно в десятичный со

знаком, десятичный без знака, восьмеричный или шестнадцатеричный

виды. (со знаком только десятичный вид, остальные без знака).

D, U, O, X

аналогично малым, но считается, что аргумент имеет тип long (т.е. D

аналогично ld).

f

действительное число типа float или double преобразуется для печати

в десятичном виде "-ddd.ddd", число цифр после десятичной точки

равно спецификации точности для аргумента. Если точность опущена,

принимается 6 цифр; если задается точность 0, не печатаются цифры и

десятичная точка.

e

действительное число типа float или double преобразуется для печати

в виде "-d.ddde+-dd", где перед десятичной точкой печатается одна

цифра, а после десятичной точки печатается столько цифр, сколько

указано в спецификации тосимволы строки печатаются до конца строки

(до символа '\0') или до исчерпания количества символов, указанного

в спецификации точности. Если точность равна 0 или опущена,

печатаются все символы до конца строки.

r

считается, что следующий аргумент является указателем на структуру

"формат - аргументы", с которыми и будет происходить дальнейшее

преобразование. первым элементом структуры должен быть указатель на

строку "формат", а следующими элементами - аргументы, над которыми

будут производится преобразования. такая структура автоматически

образуется в стеке при вызове функции с аргументами, подобными

аргументам printf(). Например:

myerror(args)

fprintf(stderr,"\n?error: %r", &args);

exits(4);

Эта функция может быть вызвана так:

myerror("ошибка %d в строке %d\n", errnum, strnum);

передача упрауления другому формату по спецификации 'r' происходит

без возврата управления вызвавшему формату. Если символ типа

преобразования не совпадает с выше перечис ленными, то этот символ

просто выводится. Таким образом можно вывести '%', задав в формате

%%".

Ни в одном из случаев отсутствующая или малая ширина поля не приводит к усечению поля. Заполнение поля (пробелами или нулями) имеет место только в том случае, когда указанная ширина поля превышает действительную ширину.

При компоновке программы в зависимости от некоторых условий могут быть исключены (для экономии памяти) функции форматных преобразований чисел с плавающей запятой. если при этом вывод чисел с пз используется, то в поле числа будет помещен один символ '?' и необходимое для заполнения поля число заполнителей.

printf() и fprintf() возвращают 0 при нормальном завершении и EOF при ошибке или конце файла. sprintf() возвращает "buffer". примеры:

для печати даты и времени в виде

sunday, july 3, 10:02

,где weekday и month являются указателями на строки, используем

следующую функцию printf:

printf("%s, %s, %d, %02d:%02d",

weekday, month, day, hour, min);

для печати числа st с точностью до пяти десятичных цифр используем:

printf("st=%.5f", st);

scanf, fscanf, sscanf

char *format;

scanf(format ,указатель ...);

file *iop;

char *format;

fscanf(iop, format ,указатель ...);

char *s;

char *format;

sscanf(s, format ,указатель ...);

scanf()считывает стандартный входной файл (stdin). fscanf() считывает

указанный входной файл. sscanf() считывает символы из строки s.

Каждая функция считывает символы, интерпретирует их в соответствии с форматом и записывает результаты в свои аргументы. аргументами каждой функции являются управляющая строка "format" описанная ниже, и ряд аргументов "указатель", указывающих на переменные для записи преобразованного ввода. Преобразование (работа функции scanf()) заканчивает при достижении конца файла или при несовпадении ожидаемого ввода с реально присутствующим.

Управляющая строка "format" содержит спецификации

преобразования, используемые для управления интерпретацией входной последовательности. Управляющая строка может содержать: пробелы, символы табуляции и новой строки, которые согласовываются с необязательными "белыми" полями во вводе; обычные символы (не'%'),

которые должны согласовываться с соответствующими символами входного потока. Если в данном месте входного потока необходимых символов не обнаруживается (лидирующее "белое" поле игнорируется), то работа scanf() заканчивается, при этом следующим вызовом getchar() будет считан тот символ, который не удалось интерпретировать, scanf() возвращает его по ungetc(). Спецификации преобразования, состоящие из символа '%', необязательного символа подавления присваивания '*', необязательной численной максимальной ширины поля и символа преобразования.

Спецификация преобразования управляет преобразованием следующего поля ввода: результат помещается в переменную, на которую указывает соответствующий аргумент, за исключением тех случаев, когда указан символ подавления присваивания '*'. Вводное поле определяется как строка символов (непробелов). Оно простирается до первого неподходящего символа или до исчерпания ширины поля (если она указана). Лидирующее "белое" поле перед полем ввода обычно (если это не оговорено особо) игнорируется. Символ преобразования указывает на вид интерпретации поля ввода. Могут применяться следующие символы преобразования:

% - в этой точке ввода ожидается одиночный символ '%',

присваивание не выполняется;

d ,o, x - ожидается целое указанного типа - десятичное,

восьмеричное или шестнадцатеричное соответственно.

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

s - ожидается символьная строка. Соответствующий аргумент

должен быть указателем на char, указывающим на массив символов, достаточный для размещения строки вместе с завершающим символом '\0', который будет добавлен. Поле ввода завершается пробелом, табуляцией или символом новой строки.

c - ожидается символ. соответствующий аргумент должен быть

указан в квадратных скобках. отметим, что лидирующее "белое" поле не подавляется. Если первым символом после квадратной скобки является '~', то набор символов в квадратных скобках рассматривается как набор "запрещенных" или "стоповых" символов - вводятся все символы до первого символа, который присутствует в оставшейся части (после '~') символов между квадратными скобками. Соответствующий аргумент должен указывать на массив символов.

Если перед d, o или x ставится 'l', это означает, что в списке аргументов находится указатель на целое число с двойной точностью (long), а не на int. Аналогично, если перед e и f ставится 'l', это означает, что используется указатель на число с плавающей точкой двойной точности (double), а не float. Аналогичного эффекта можно добиться, используя для спецификации преобразований большие буквы, как в printf. Если символам преобразования d,o или x предшествует 'h',это означает, что используется указатель на короткое целое (short), а не на int (в данной реализации short совпадает с int).Функции scanf(), fscanf(), sscanf() возвращают число присвоенных элементов ввода. Необходимо отметить, что если присут­ствующее поле не подходит для указанной спецификации преобразования (например символьный ввод для "%d" и т.п.), то спецификация пропускается и преобразование не выполняется. Если ни одного присвоения не произошло и достигнут конец файла, то будет возвращен EOF (-1). Примеры:

int i;

float x;

char name[50];

scanf("%d%f%s", &i, &x, name);

При вводе следующей строки:

25 54.32e-1 tompson

scanf() присвоит i значение 25, x - значение 5.432 и name будет

содержать "tompson\0". Возвращено будет число 3. При вводе строки

2aaa

i будет присвоено значение 2, f останется без изменений (для него нет

подходящего поля, спецификация преобразования игнорируется), name

будет содержать "aaa\0". возвращено будет число 2.

atoi

char *str; /* строка с числом */

atoi(str);

Преобразует строку символов ASCII в десятичное.

[" "\t]*[+-]?[0-9]*

ведущие пробелы, табуляции и знак '+' игнорируются, знак '-'

обрабатывается обычным образом. Преобразование заканчивается на

первом неподходящем символе. Если число не помещается в слово,

происходит усечение до 16 бит. Возвращает число. Ошибок нет. Если

преобразования не было вообще, возвращается число 0.

atoo

char *str;

atoo(str);

строку символов ASCII в восьмеричное число. Все остальное как atoi.

atol

char *str;

long

atol(str);

преобразует строку символов ASCII в длинное десятичное. происходит

усечение до 32 бит. Все остальное как atoi

atof

char *str;

double

atof(str);

преобразует строку символов ASCII в длинное десятичное с плавающей

точкой (double). Строка ожидается в виде (в нотации lex):

[" "\T]*[+-]?[0-9]*(\.[0-9]*)?[Ee]?((-)?[0-9]+)?

или, по русски, в виде необязательной подстрочки пробелов и

табуляций, необязательного знака, строки цифр, возможно содержащей

десятичную точку, необязательного символа 'Е' (на любом регистре) и

необязательного целого со знаком. Если значение превышает набольшее

представимое, то возвращается наибольшее представимое число и

устанавливается ошибка "E_RAN" в $$ferr.

ecvt, fcvt, gcvt - преобразования для вывода чисел с плавающей

запятой

double value;

int ndigit, *decpt, *sign;

char *

ecvt(value, ndigit, decpt, sign);

char *

fcvt(value, ndigit, decpt, sign);

char *buf;

char *

gcvt(value, ndigit, buf);

ecvt() - значение value в строку цифр ASCII длиной ndigit и возвращает указатель на нее. Позиция десятичной точки относительно начала строки возвращается через decpt: нулевое значение означает, что точка стоит пере первым символом строки, отрицательное значение означает, что десятичная точка стоит слева от строки. Если value отрицательно, то через sign возвращается ненулевое значение, и

нулевое в противном случае. Младшая цифра округляется.

fcvt() аналогична ecvt(), однако ndigit означает не общее число цифр, а число цифр после запятой.

gcvt() преобразует значение value в строку цифр ASCII в буфере, на которы указывает buf и возвращает buf. В строке, возвращаемой gcvt() присутствует до ndigit значащих цифр (меньше, если число короткое). Строка пригодна для печати, причем формат строки - 'e' Jили 'f', выбирается по минимуму длины строки, необходимой для представления данного числа в этих форматах.

Поясним это:

число 1.1 может быть представлено:

1.1 - формат 'f'

1.1e+00 - формат 'e'.

длина первого представления меньше, поэтому будет выбрано оно;

число 123000000 может быть представлено так:

123000000 - формат 'f'

1.23Е+08 - формат 'e'

в этом случае будет выбрано второе представление.

gcvt() вызывает ecvt(). необходимо отметить, что эти функции возвращают указатели на внутренние статические буфера, которые будут перезаписываться при каждом вызове функций.