КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Использование встроенного отладчика. 1 страница
Использование функций printf() и fprintf(). Использование функций getw() и putw(). Функция strcpy(). Функция strcmp(). Функция strcat(). Функция strlen(). Использование функций gets(), puts(), fgets() и fputs(). Выделение памяти. Указатели и строки. Массивы символьных строк. Явное задание размера памяти. Массивы символьных строк и их инициализация. Строковые константы. Использование функций getch() и putch(). Использование функций getchar(), putchar(),fgetchar() и fputchar(). Простая программа сжатия файла. Использование функций getc(), putc(), fgetc() и fputc(). Закрытие потоков. Изменение буфера потока. Переназначение ввода и вывода. Текстовые файлы с буферизацией. Файлы. Открытие потоков. Включение библиотеки. Включение файла. Автоматический доступ. 17.3. Потоковый ввод-вывод. 17.4. Связь с файлами. 17.5. Понятие файла. 17.6. Потоковые функции. 17.7. Низкоуровневый ввод и вывод в С. 17.8. Ввод и вывод символов. 17.9. Определение строк в программе. 17.9.3. Различия: массив и указатель. 17.10. Ввод и вывод строк. 17.11. Функции, работающие со строками. 17.12. Создание собственных функций ввода/вывода. 17.13. Проверка и преобразование символов. 17.14. Преобразования символьных строк: atoi(), atof(). 17.15. Ввод и вывод целых чисел. 17.16. Форматированный вывод. 17.17. Использование функций fseek(), ftell() и rewind(). 17.18. Форматированный ввод. 17.19. Использование функций scanf(), fscanf() и sscanf(). 17.20. Распределение памяти: malloc() и calloc(). 17.21. Другие библиотечные функции.
3. Библиотека языка С и ввод-вывод. Всякий раз, когда нам нужно использовать такие функции, как printf(), getchar() и strlen(), мы обращаемся в библиотеку языка Си. Она содержит множество функций и макроопределений. Библиотеки меняются от системы к системе, но есть ядро функций (называемое стандартной библиотекой), которое используется чаше всего. Здесь мы рассмотрим пятнадцать наиболее общих из этих функций, уделяя больше внимания функциям ввода-вывода и использованию файлов. Однако сначала давайте поговорим о том, как пользоваться библиотекой.
7.16. Стандартные библиотеки С и C++. Некоторые действия постоянно выполняются во многих программах и программируются практически всеми разработчиками. Для примера можно взять операцию извлечения квадратного корня. В математических функциях для извлечения квадратного корня используются комбинации основных арифметических операций: сложения, вычитания, умножения и деления. Каждому программисту бессмысленно создавать собственную процедуру для вычисления корня и затем встраивать ее в программу. Подобные проблемы решены в С и C++ при помощи библиотек функций для выполнения подобных вычислений. Имея библиотеку, достаточно написать один оператор с вызовом нужной функции. В этом разделе рассматриваются функции, обычно поставляемые с компилятором С и C++. Чаще всего эти функции существуют не в виде исходного текста, а в скомпилированном виде. При выполнении компоновки для получения законченной программы код библиотечных функций объединяется с откомпилированным кодом, написанным программистом. Библиотечные функции выполняют не только математические действия, но и другие, часто встречающиеся операции. Например, имеются библиотечные функции для чтения и записи файлов на дисках, управления памятью, ввода/вывода и множества других операций. Библиотеки не являются частью стандартного С или C++, но практически каждая система проектирования предлагает определенные библиотечные функции. Большинство библиотечных функций написаны так, что они используют информацию, содержащуюся в определенных файлах, поставляемых с системой. Следовательно, при использовании библиотек эти файлы должны быть включены в программу и обрабатываться компилятором Visual C/C++. Обычно подобные файлы имеют расширение.h и называются заголовочными файлами. В табл. 6.7 перечислены заголовочные файлы, поставляемые с Microsoft Visual C/C++.
Таблица 6.7. Заголовочные файлы Microsoft Visual C/C++
В общем, различные библиотечные функции требуют разных заголовочных файлов. Заголовочные файлы, необходимые для некоторой функции, перечислены в ее описании. Например: для функции sqrt() необходимы объявления, находящиеся в заголовочном файле math.h. Все библиотечные функции и связанные с ними заголовочные файлы описаны в справочнике Microsoft Visual C/C++ Run-Time Library Reference. Далее приведен краткий список библиотек компилятора Visual C/C++, объединенных в функциональные группы: · Функции классифицирующие · Функции преобразования типов · Функции управления каталогами · Функции диагностики · Функции графики · Функции ввода/вывода · Функции интерфейсов (DOS, 8086, BIOS) · Функции манипулирования с данными · Функции математические · Функции выделения памяти · Функции управления процессами · Функции стандартные · Функции отображения текстовых окон · Функции времени и дат
Посмотрите в вашем справочном руководстве детальное описание отдельных функций, имеющихся в каждой библиотеке. После чтения этой главы вы должны разбираться в основных типах данных и операциях языка С.
7.17. Доступ в библиотеку языка Си. Получение доступа к библиотеке зависит от системы, поэтому вам нужно посмотреть в своей системе, как применять наиболее распространенные операторы. Во-первых, есть несколько различных мест расположения библиотечных функций. Например, getchar() обычно задают как макроопределение в файле stdio.h, в то время как strlen() обычно хранится в библиотечном файле. Во-вторых, различные системы имеют разные способы доступа к этим функциям. Вот три из них.
7.17.1. Автоматический доступ. Во многих больших системах UNIX вы только компилируете программы, а доступ к более общим библиотечным функциям выполняется автоматически.
7.17.2. Включение файла. Если функция задана как макроопределение, то можно директивой #include включить файл, содержащий ее определение. Часто подобные функции могут быть собраны в соответствующим образом названный заголовочный файл. Например, некоторые системы имеют файл ctype.h, содержащий макроопределения, задающие тип символа: прописная буква, цифра и т. д.
7.17.3. Включение библиотеки. На некотором этапе компиляции или загрузки программы вы можете выбрать библиотеку. В нашей системе, например, есть файл lc.lib, содержащий скомпилированную версию библиотечных функций, и мы предлагаем редактору связей IBM PC использовать эту библиотеку. Даже система, которая автоматически контролирует свою стандартную библиотеку, может иметь другие библиотеки редко применяемых функций, и эти библиотеки следует запрашивать явно, указывая соответствующий признак во время компиляции. Очевидно, мы не сможем рассмотреть все особенности всех систем, но эти три примера должны показать, что вас ожидает. Теперь мы готовы к рассмотрению некоторых функций. Добавим функции открытия и закрытия файлов, связи с файлами, проверки и преобразования символов, преобразования строк, функцию выхода и функции распределения памяти.
7.18. Потоковый ввод-вывод. Многие широко используемые языки высокого уровня имеют механизмы ввода/вывода, позволяющие создавать нетривиальные алгоритмы для получения и отображения сложных структур данных. Это не относится к языку С, в котором имеется весьма развитая библиотека функций ввода/вывода, хотя, исторически, ввод/вывод никогда не являлся частью самого языка С. Если вы пользуетесь только простыми операторами ввода/вывода, подобными операторам Паскаля readln и writeln, то такая ситуация может вас удивить. Здесь описываются более 20 различных способов организации ввода/вывода в С. Библиотека стандартных функций ввода/вывода С позволяет считывать данные и записывать их в файлы и устройства. Однако в самом языке С отсутствуют какие-либо предопределенные файловые структуры. В С все данные обрабатываются как последовательность байт. Имеется три основных типа функций ввода/вывода: потоковые, работающие с консолью и портами, низкоуровневые. В потоковых функциях ввода/вывода файлы или объекты данных рассматриваются как поток отдельных символов. Выбирая соответствующую потоковую функцию, вы можете обрабатывать данные любого необходимого размера или формата, начиная от отдельных символов и заканчивая большими, сложными структурами данных. На техническом уровне, когда программа открывает файл для ввода/вывода при помощи потоковых функций, открытый файл связывается с некоторой структурой типа FILE (предопределенной в stdio.h), содержащей базовую информацию об этом файле. После открытия потока возвращается указатель на файловую структуру. Указатель файла, иногда называемый указателем потока или потоком, используется для ссылки к файлу при всех последующих операциях ввода/вывода. Все потоковые функции ввода/вывода обеспечивают буферизированный, форматированный или неформатированный ввод и вывод. Буферизированный поток обеспечивает место для промежуточного хранения всей информации, вводимой из потока или записываемой в поток. Поскольку дисковый ввод/вывод занимает довольно много времени, буферизация потока разгружает приложение. Вместо того чтобы вводить данные из потока по одному символу или по одному элементу данных, потоковые функции ввода/вывода получают данные поблочно. Когда приложению необходимо обработать введенную информацию, оно просто обращается к буферу, что гораздо быстрее. Когда буфер становится пустым, выполняется считывание с диска другого блока. Во многих языках высокого уровня существует одна проблема с буферизированным вводом/выводом, которую нужно принимать во внимание. Например: если ваша программа выполнила несколько операторов вывода, которые не заполнили буфер вывода, и запись на диск не произошла, то по завершении программы эта информация будет потеряна. Для решения этой проблемы обычно выполняется вызов соответствующей функции для очистки буфера. В отличие от других языков высокого уровня, в языке С данная проблема с буферизированным вводом/выводом решается путем автоматической очистки содержимого буфера по завершении программы. Конечно, хорошо написанное приложение не должно рассчитывать на эти автоматические действия; все действия программы должны описываться в явном виде. Дополнительное замечание: если вы используете потоковый ввод/вывод и приложение заканчивается с аварийным остановом, то буферы вывода могут оказаться неочищенными, что приведет к потере данных. Аналогичным образом выглядят процедуры, работающие с консолью и портами; их можно рассматривать как расширенные потоковые функции. Они позволяют читать и писать на терминал (консоль) или в порт ввода/вывода (например, в порт принтера). Функции портов ввода/вывода выполняют простое побайтное считывание и запись. Функции ввода/вывода на консоль обеспечивают несколько дополнительных возможностей. Например, можно определить: введен ли с консоли символ или имеют ли вводимые символы эхо-отображение на экране. Последним типом ввода и вывода является низкоуровневый. Функции низкоуровнего ввода/вывода не выполняют никакой буферизации и форматирования; они непосредственно обращаются к средствам ввода и вывода операционной системы. Эти функции позволяют обращаться к файлам и периферийным устройствам на более низком уровне, чем это делают потоковые функции. При открытии файла на этом уровне возвращается описатель файла (file handle), представляющий собой целое число, использующееся затем для обращения к этому файлу при последующих операциях. В общем случае не рекомендуется смешивать функции потокового ввода/вывода с низкоуровневыми. Поскольку потоковые функции являются буферизированными, а низкоуровневые — нет, при обращении к файлу или устройству при помощи двух разных способов возможны рассогласование или даже потеря данных в буферах. Поэтому для каждого конкретного файла необходимо использовать либо потоковые, либо низкоуровневые функции. В табл. 17.1 перечислены наиболее часто используемые в С функции потокового ввода/вывода.
Таблица 17.1. Функции С потокового ввода и вывода
7.19. Связь с файлами. Часто нам бывает нужна программа получения информации от файла или размещения результатов в файле. Один способ организации связи программы с файлом заключается в использовании операций переключения < и >. Этот метод прост, но ограничен. Например, предположим, вы хотите написать диалоговую программу, которая спрашивает у вас названия книг (звучит фамильярно?), и вы намерены сохранить весь список в файле. Если вы используете переключение как, например, в
books > bklist
то ваши диалоговые приглашения также будут переключены на bklist. И тогда не только нежелательная чепуха запишется в bklist, но и пользователь будет избавлен от вопросов, на которые он, как предполагалось, должен отвечать. К счастью, язык Си предоставляет и более мощные методы связи с файлами. Один подход заключается в использовании функции fopen(), которая открывает файл, затем применяются специальные функции ввода-вывода для чтения файла или записи в этот файл и далее используется функция fclose() для закрытия файла. Однако прежде чем исследовать эти функции, нам нужно хотя бы кратко познакомиться с сущностью файла.
7.20. Понятие файла. Для нас файл является частью памяти, обычно на диске, со своим именем. Мы считаем, например, stdio.h именем файла, содержащего некоторую полезную информацию. Для операционной системы файл более сложен, но это системные проблемы, а не наши. Однако мы должны знать, что означает файл для программы на языке Си. В предлагаемых для обсуждения функциях, работающих с файлами, язык Си «рассматривает» файл как структуру. Действительно, файл stdio.h содержит определение структуры файла. Вот типичный пример, взятый из IBM-версии компилятора Lattice С:
struct _iobuf { char *_ptr; /* текущий указатель буфера */ int _cnt; /* текущий счетчик байтов */ char *_ base; /* базовый адрес буфера ввода-вывода*/ char _ flag; /* управляющий признак */ char _ file; /* номер файла */ };
#define FILE struct _iobuf /* краткая запись */
Здесь мы не собираемся разбираться детально в этом определении. Главное состоит в том, что файл является структурой, и что краткое наименование шаблона файла — FILE. (Многие системы используют директиву typedef для установления этого соответствия.) Таким образом, программа, имеющая дело с файлами, будет использовать тип структуры FILE, чтобы делать так. Имея это в виду, мы сможем лучше понять операции над файлами.
7.21. Потоковые функции. Для того чтобы использовать потоковые функции, в программу должен быть включен файл stdio.h. В этом файле содержатся описания констант, типов и структур, используемых в потоковых функциях, а также — прототипы и макроопределения этих функций. Многие константы, предопределенные в файле stdio.h, могут быть полезны для вашей программы. Например: EOF определяется как значение, возвращаемое функциями ввода при обнаружении конца файла; NULL определяется как указатель на null. Кроме того: FILE определяет структуру используемую для хранения информации о потоке, a BUFSIZ определяет размер по умолчанию буферов потока.
7.21.1. Открытие потоков. Перед тем как выполнять операции ввода и вывода для потока, можно с помощью одной из трех функций открыть этот поток: fopen(), fdopen() или freopen(). В момент открытия потока задаются режим файла и способ доступа. Файл потока может открываться для считывания, записи или для считывания/записи в текстовом или двоичном режиме.
Дата добавления: 2015-01-03; Просмотров: 947; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |