Методические указания для практических занятий по курсу Языки программирования высокого уровня
Цель занятия
Целью занятия является практическое изучение методов применения стандартных библиотечных функций
буферизованного ввода-вывода системы программирования C для форматирования текстовых файлов.
Формулировка задания
Требуется разработать программу BOUND для форматирования границ строк текстовых документов по заданной ширине. Исходный текстовый документ, подлежащий форматированию, может состоять из произвольного числа строк различной длины, где слова разделены символами пробелов или табуляции. Строки исходного текста группируются в текстовые абзацы, разделенные пустыми строками, в которых нет других символов, кроме пробелов и/или табуляций. Исходный текстовый документ может содержать однострочные заголовки, которые отделены от абзацев пустыми строками, и концептуально эквивалентны однострочным абзацам.
После форматирования должен быть получен типографический текст, где все строки, кроме последних строк абзацев, имеют одинаковую заданную ширину, а последние строки абзацев выровнены по левой границе. Выравнивание границ строк должно достигаться путем переноса лишних слов на следующую строку и регулировки размера промежутков из пробелов между словами текста. При этом размеры промежутков в пределах каждой строки не должны отличаться больше, чем на один пробел.
Исходными данными для программы BOUND являются имена текстовых файлов, где находится подлежащий выравниванию текст и должен быть сосредоточен результат его форматирования, а также требуемая ширина типографического текста. Указанные параметры должны передаваться программе BOUND через аргументы командной строки ее вызова, где каждому из них предшествует идентифицирующий ключ -i, -o или -l, которые обозначают, что следующий аргумент следует интерпретировать как имя входного файла, имя выходного файла и требуемый размер строки типографического текста, соответственно. Использование ключей позволяет перечислять параметры программы BOUND в произвольном порядке. Отсутствие любого ключа или параметра командной строки должно блокировать выполнение программы BOUND.
В результате выполнения программы BOUND должен быть создан текстовый файл с заданным именем, содержащий полученный типографический текст с требуемой шириной строк. В операционную среду вызова программы BOUND в этом случае должен возвращаться нулевой код. Если результирующий файл не может быть создан, программа BOUND должна возвращать ненулевой код и отображать соответствующее диагностическое сообщение через стандартный поток диагностики ошибок.
Программа BOUND должна быть разработана в системе программирования C, с учетом требований современных стандартов ANSI/ISO C, на основе концепций структурного и функционально-ориентированного программирования. Исходный код программы BOUND должен допускать трансляцию в любой реализации компилирующей системы программирования C. Выполняемый код программы BOUND должен быть сформирован для эксплуатации в среде OS UNIX.
Алгоритм форматирования текста
В программе BOUND должен быть реализован алгоритм форматирования, ориентированный на построчную обработку содержимого исходного текста. Его основу составляют циклы обработки строк исходного текста и слов в каждой полученной строке для формирования выходных строк, которые образуют результирующий типографический текст. Информационную поддержку итераций указанных циклов обеспечивают три символьных буфера: входной, выходной и промежуточный. Каждый из буферов имеет фиксированный размер, который гарантированно превышает длину любой строки исходного текста.
Итерации внешнего цикла алгоритма форматирования должны продолжаться, пока не достигнут конец исходного текста. На каждой итерации очередная строка исходного текста размещается во входном буфере для обработки ее слов во внутреннем цикле алгоритма форматирования. Его итерации должны продолжаться, пока не рассмотрены все слова текущего входного буфера.
Итерации внутреннего цикла алгоритма форматирования должны обеспечивать разбиение входного буфера на отдельные слова, которые последовательно накапливаются в промежуточном буфере через один пробел. Добавление слов в промежуточный буфер может продолжаться, пока его текущий размер не превышает предел, установленный шириной результирующего типографического текста. Когда превышен указанный предел, все слова, накопленные в промежуточном буфере, должны быть последовательно переписаны в выходной буфер, содержимое которого предварительно инициализируется пробелами. Взаимное расположение слов в выходном буфере должно обеспечивать выравнивание его содержимого по требуемой ширине слов результирующего типографического текста.
Для выравнивания выходного буфера по заданной ширине строк необходимо вычислить величины промежутков из пробелов между словами в нем. Базовую величину промежутка определяет результат целочисленного деления разности между заданной шириной типографического текста и суммарной длиной слов на количество промежутков между словами. Остаток от деления указанных величин должен быть равномерно распределен между всеми промежутками, путем добавления не больше, чем одного пробела между каждой парой слов. Таким образом, расположение каждого слова в выходном буфере рекурсивно определяется длиной предыдущего слова плюс величина промежутка между словами.
Сформированный выходной буфер должен быть дополнен символом перевода строки и переписан в результирующий типографический текст. После этого промежуточный буфер должен быть очищен и продолжены итерации внутреннего цикла для обработки оставшихся слов входного буфера. Когда все слова из входного буфера будут перенесены в промежуточный буфер, во входном буфере должна быть размещена следующая строка исходного текста, которая предоставляет свои слова для заполнения промежуточного буфера на следующей итерации внутреннего цикла алгоритма форматирования.
Следует отметить, что иначе должны обрабатываться пустые строки исходного текста, которые идентифицируют границы абзацев. При получении пустой строки во входной буфер, итерации внутреннего цикла алгоритма форматирования не должны выполняться, поэтому содержимое промежуточного буфера, сохраняется неизменным. С другой стороны расположение слов в промежуточном буфере, где слова выровнены по левой границе и разделены одним пробелом, соответствует требуемому формату последней строки абзаца типографического текста. Поэтому при получении пустой строки достаточно скопировать промежуточный буфер в выходной буфер, дополнив его парой символов перевода строки и записать содержимое полученного выходного буфера в результирующий типографический текст. После этого необходимо очистить промежуточный буфер для выполнения последующих итераций алгоритма форматирования. Необходимо также помнить, что рассмотренную процедуру обработки конца абзаца следует выполнить после выхода из внешнего цикла алгоритма форматирования, если последняя строка исходного текста не является пустой.
Очевидно, что рассмотренная процедура обработки конца абзаца должна выполняться только при непустом промежуточном буфере, когда в нем есть хотя бы одно слово. Промежуточный буфер автоматически оказывается пустым, если исходный текст содержит фрагменты из двух и более расположенных подряд пустых строк или когда исходный текст начинается с пустой строки. В этих ситуациях достаточно записать в выходной буфер и, соответственно, в результирующий типографический текст только символ перевода строки при получении каждой пустой строки исходного текста во входной буфер.
Структура программы
В соответствии с принципами структурного программирования исходный код программы BOUND целесообразно разделить на несколько прикладных функций, реализующих различные операции алгоритма форматирования. Обращение к ним должна обеспечивать основная функция main программы BOUND.
По характеру обработки данных прикладные функции программы BOUND должны разделяться на три группы. Первая группа функций предназначена для перегрузки операций буферизованного ввода-вывода, чтобы ориентировать их на обработку буферов алгоритма форматирования. Вторая группа функций должна обеспечивать выполнение операций алгоритма форматирования. В третью группу следует включить функции анализа аргументов командной строки вызова программы BOUND.
Порядок вызова прикладных функций в программе BOUND регламентирует основная функция main по следующей схеме. Сначала необходимо выполнить анализ аргументов командной строки, чтобы получить из нее имена файлов исходного и результирующего типографического текста, а также требуемый размер строк последнего. Затем нужно открыть потоки буферизованного ввода-вывода для последующей обработки исходного текста в соответствии с алгоритмом форматирования. После его выполнения нужно закрыть потоки ввода-вывода и завершить программу BOUND возвратом нулевого кода в операционную среду ее вызова.
Следует учесть, что каждый следующий этап в рассмотренной схеме должен выполняться только при корректном завершении предыдущего. В частности, при нарушении формата командной строки или невозможности открыть потоки буферизованного ввода-вывода в требуемом режиме должно происходить аварийное завершение программы BOUND с возвратом ненулевого кода в операционную среду ее вызова и отображением соответствующей диагностики ошибки.
Структуры данных
Обмен данными между прикладными функциями программы BOUND должен осуществляться через структуру буферов FORMBUF. Эта структура должна быть определена в блоке основной функции main и адресована во все прикладные функции программы BOUND, где доступна декларация ее полей.
Информационную основу структуры буферов FORMBUF должны составлять три буферных поля, которые представляют собой символьные массивы с именами, например, inbuf, outbuf и workbuf. В основном они предназначаются для буферизации входных, выходных и промежуточных данных при выполнении итераций алгоритма форматирования. Кроме того эти буферные поля могут быть использованы для получения аргументов командной строки вызова программы BOUND перед выполнением итераций алгоритма форматирования.
Буферные поля структуры FORMBUF должны иметь фиксированный размер, который может быть макроопределен величиной константы BUFSIZ из заголовочного файла <stdio.h> системы программирования C. Независимо от конкретной реализации системы программирования C значение константы BUFSIZ не может быть меньше, чем 512 байт, следовательно, достаточно для корректного форматирования текстов в большинстве практически интересных случаев.
Дополнительно к буферным полям в структуре FORMBUF нужно предусмотреть еще несколько полей. В частности, необходимо отдельное поле, например, word для хранения указателя слов входного буфера, два поля, например, fpin и fpout для указателей потоков ввода-вывода, а также поле, которое фиксирует целочисленный размер строк типографического текста. Его можно назвать, например, limit. Перечисленные дополнительные поля должны обеспечивать хранение данных типов char*, FILE* и int, соответственно.
Таким образом структура FORMBUF должна состоять из семи полей, среди которых три буфера, два указателя потоков, указатель слов и заданный размер строк результирующего текста. Указанный состав полей должен гарантировать унификацию интерфейсов обмена данными между прикладными функциями программы BOUND.
Анализ командной строки
Для анализа аргументов командной строки вызова программы BOUND следует предусмотреть 3 прикладные функции: gramma, usage и convert. Обращение к ним должно быть специфицировано в начале исходного кода основной функции main программы BOUND.
Прикладная функция gramma должна обеспечивать грамматический разбор аргументов командной строки вызова программы BOUND. Ее следует передать число аргументов и адрес вектора аргументов вызова программы BOUND, а также указатель на структуру FORMBUF. Основу ее исходного кода должен составлять цикл поиска ключевых параметров вектора аргументов, которые идентифицируют следующий аргумент как имя файла исходного текста, имя файла результирующего типографического текста или требуемый размер строк его абзацев.
Для сравнения аргументов вектора с ключами необходимо применить библиотечную
функцию strcmp. Обнаруженные имена исходного и результирующего файлов нужно скопировать, соответственно, в поля inbuf и outbuf структуры FORMBUF. Копию аргумента, который определяет размер строк результирующего типографического текста, следует сохранить в поле workbuf структуры FORMBUF. Копирование указанных аргументов должен обеспечить вызов библиотечной
функции strcpy. При этом буферные поля структуры FORMBUF должны быть предварительно инициализированы нулевым кодом.
Результат грамматического разбора аргументов командной строки вызова программы BOUND определяет величина логического произведения (&) кодов начальных символов трех буферных полей структуры FORMBUF. Прикладная функция gramma должна передавать значение этого произведения в основную функцию main через целочисленный код возврата. Нулевой код возврата означает отсутствие хотя бы одного из ключевых или информативных параметров в командной строке вызова программы BOUND.
При нулевом коде возврата прикладной функции gramma из основной функции main должна вызываться прикладная функция usage. Она должна отображать через поток протокола стандартной диагностики (stderr) информационное сообщение, содержащее описание корректного формата командной строки вызова программы BOUND. Для отображения указанной диагностики должна применяться библиотечная
функция fprintf. Прикладная функция usage всегда должна завершаться возвратом отрицательного числа, которое через
оператор return основной функции main передается в операционную среду вызова программы BOUND, обозначая аварийное завершение ее выполнения.
Любой ненулевой код возврата прикладной функции gramma означает успех грамматического разбора аргументов командной строки вызова программы BOUND. При этом вызов диагностической функции usage не происходит и выполнение программы BOUND должно быть продолжено вызовом прикладной функции convert, которой необходимо передать указатель на структуру FORMBUF.
Прикладная функция convert вызывается для преобразования символического представления требуемого размера строк результирующего типографического текста, которое было сохранено в поле workbuf структуры FORMBUF функцией gramma, в целочисленный формат поля limit. Для выполнения указанного преобразования можно применить библиотечные функции atoi или sscanf. Его результат нужно сохранить в поле limit структуры FORMBUF и вернуть в основную функцию main. Если полученное значение отрицательно, равно 0 или меньше некоторой разумной величины, например, 32, то дальнейшее выполнение программы BOUND должно быть аварийно завершено с вызовом диагностической функции usage в основной функции main.
Перегрузка операций ввода-вывода
Для перегрузки стандартных операций ввода-вывода в программе BOUND целесообразно предусмотреть 4 прикладные функции: textopen, getbuf, putbuf и closetext. Единственным параметром каждой из них является указатель на структуру FORMBUF. Исходный код этих функций должен предусматривать вызов библиотечных функций буферизованного ввода-вывода, прототипы которых декларирует заголовочный файл <stdio.h> системы программирования C.
Прикладная функция textopen должна вызываться в основной функции main после разбора аргументов командной строки вызова программы BOUND с целью открыть потоки ввода строк из файла исходного текста и вывода строк в результирующий файл типографического текста. Чтобы открыть указанные потоки ввода-вывода, в ее исходном коде должно быть специфицировано обращений к библиотечной функции
fopen. Имена файлов, для обработки которых открываются потоки ввода-вывода, должны быть доступны через поля inbuf и outbuf структуры буферов FORMBUF, где они сохраняются при разборе аргументов командной строки. При этом файл, содержащий исходный текст должен быть открыт в режиме чтения, а результирующий файл для сохранения форматированного текста должен быть открыт в режиме записи. Если любой из указанных файлов не может быть открыт в требуемом режиме доступа, то функция textopen должна возвращать значение системной переменной errno, содержащей код ошибки, в основную функцию main, которая через оператор return передает его в операционную среду вызова программы BOUND, блокируя ее дальнейшее выполнение. Для визуальной диагностики ошибок в функции textopen должен быть предусмотрен вызов библиотечной
функции perror, которой передается имя соответствующего файла. Если оба файла успешно открыты, то указатели их потоков сохраняются в соответствующих полях структуры FORMBUF и могут быть использованы для реализации буферизованного ввода-вывода в других функциях этой группы, а функция textopen завершается с нулевым кодом возврата.
Прикладная функция getbuf должна выполнять операцию буферизованного ввода строк из файла исходного текста через поток ввода путем обращения к библиотечной функции fgets. Предельную длину получаемых строк в ней должно ограничивать значение макроопределения
BUFSIZ из заголовочного файла <stdio.h> системы программирования C. Для получения очередной строки исходного текста должно быть адресовано поле inbuf структуры буферов FORMBUF, представляющее входной буфер алгоритма форматирования. Для идентификации потока ввода используется поле указателя потока fpin также из структуры FORMBUF. Прикладная функция getbuf должна вызываться во внешнем цикле алгоритма форматирования и возвращать адрес входного буфера или значение нулевого указателя NULL для идентификации конца файла исходного текста.
Прикладная функция putbuf должна обеспечивать буферизованный вывод в поток записи результирующего типографического текста строки, полученной в выходном буфере алгоритма форматирования. Для реализации вывода должна применяться библиотечная функция fputs. Ее аргументы должны адресовать буферное поле outbuf, представляющее выходной буфер алгоритма форматирования, и поле указателя потока вывода fpout структуры FORMBUF. Функция putbuf должна вызываться в циклах алгоритма форматирования, когда заполнен выходной буфер. Ее код возврата должен быть равен нулю. Нулевой код возврата этой функции можно использовать для инициализации длины и содержимого промежуточного буфера алгоритма форматирования.
Прикладная функция closetext должна закрывать потоки обработки файлов, содержащих исходный и результирующий типографический текст, освобождая указатели потоков fpin и fpout в структуре FORMBUF. Для выполнения этих действий следует использовать библиотечную функцию fclose. Прикладная функция closetext должна быть вызвана в основной функции main перед завершением работы программы BOUND. Ее код возврата должен быть равен нулю и передаваться оператору return, который завершает спецификацию основной функции main программы BOUND.
Функции форматирования
Для выполнения операций алгоритма форматирования текста в программе BOUND необходимо предусмотреть 6 прикладных функций: getword, chklimit, putword, expander, trailer и gap. Управление ими должна обеспечивать прикладная функция format, которая должна вызываться в основной функции main после инициализации потоков ввода-вывода. Единственным параметром всех функций форматирования должен быть указатель на структуру FORMBUF. Исходный код перечисленных прикладных функций должен предусматривать обращение к библиотечным функциям обработки символьных строк, форматы вызова которых декларируются в заголовочном файле <string.h> системы программирования C.
Прикладная функция getword должна обеспечивать разбиение содержимого входного буфера inbuf структуры FORMBUF на отдельные слова. Считается, что слова во входном буфере разделяют символы пробелов и табуляций, а последнее слово завершает символ перевода строки. Для выделения слов следует использовать библиотечную функцию strtok, которой передается адрес входного буфера inbuf при поиске первого слова или NULL при поиске остальных слов. Адрес очередного слова должен сохраняться в поле word структуры FORMBUF и передаваться через код возврата прикладной функции getword. Когда содержимое входного буфера inbuf исчерпано, прикладная функция getword должна возвращать значение константы NULL.
Прикладная функция chklimit должна осуществлять проверку возможности дополнить рабочий буфер wordbuf очередным словом входного буфера inbuf, которое адресует поле word структуры FORMBUF. Эта проверка основана на том, что суммарная длина слов в рабочем буфере слов не должна превышать требуемый размер строк результирующего типографического текста, который устанавливает значение поля limit структуры FORMBUF. Для вычисления длины рабочего буфера слов workbuf и текущего слова word необходимо использовать библиотечную
функцию strlen. Результат проверки определяет знак разности между суммой вычисленных длин и лимитирующим значением поля limit структуры FORMBUF. Любое положительное значение разности означает невозможность дополнить рабочий буфер слов очередным словом. Полученная величина разности должны быть передана через целочисленный код возврата прикладной функции chklimit.
Прикладная функция putword должна применяться для добавления текущего слова, адресованного полем word, в рабочий буфер слов workbuf структуры FORMBUF. После слова необходимо добавить один символ пробела, чтобы обеспечить разделение слов в буфере workbuf. Для добавления слов и пробелов нужно использовать библиотечную
функцию strcat. Целочисленный код возврата прикладной функции putword должен идентифицировать текущий размер рабочего буфера слов, для вычисления которого следует применить библиотечную функцию strlen.
Прикладная функция expander предназначена для выравнивания слов, которые накоплены в рабочем буфере слов wordbuf, по ширине, заданной полем limit структуры FORMBUF. Для выполнения этой процедуры нужно предварительно установить текущий размер рабочего буфера слов и количество промежутков между его словами. Текущий размер рабочего буфера слов определяется эффективной длиной поля wordbuf структуры FORMBUF, которая измеряется с помощью библиотечной функции strlen. Количество промежутков однозначно определяет число пробелов в рабочем буфере слов, потому что каждую пару слов в нем по построению разделяет один символ пробела. Число пробелов можно найти, используя циклический вызов библиотечной
функции strrchr. При этом целесообразно заменить каждый пробел на символ с нулевым кодом '\0' для удобства последующей обработки завершаемых им слов.
Обладая этой информацией, можно вычислить базовый размер промежутка из пробелов между словами и остаточное число пробелов, которые должны быть равномерно распределены между словами. После этого нужно переписать все слова из рабочего буфера слов в выходной буфер, заданный полем outbuf структуры FORMBUF, дополняя их соответствующим числом промежуточных пробелов между словами. Для копирования слов и формирования промежутков между ними в выходном буфере следует организовать циклический вызов библиотечных функций strcpy, strlen и memset. При этом, копирование каждого очередного слова в выходной буфер должно осуществляться со смещением относительно предыдущего слова, величина которого учитывает размер вычисленного промежутка между словами. После последнего слова в выходной буфер вместо разделительных пробелов нужно записать символ перевода строки '\n' и инициализировать рабочий буфер слов.
Прикладная функция trailer необходима для формирования последней строки любого абзаца, которая должна быть выровнена по левой границе текста. Указанное выравнивание достигается путем копирования всех слов рабочего буфера workbuf в выходной буфер outbuf структуры FORMBUF, например, с помощью библиотечной
функции strcpy. После копирования слов необходимо инициализировать рабочий буфер слов и дополнить выходной буфер парой символов перевода строки. Один символ перевода строки должен обозначать конец абзаца, а другой - завершение его последней строки. При пустом рабочем буфере в выходной буфер вместо копирования слов нужно просто записать один символ перевода строки, чтобы отобразить в результирующем типографическом тексте пустую строку исходного текста.
Распознавание пустых строк, которые не содержат других символов, кроме необязательных символов пробелов и/или табуляции, и разделяют абзацы исходного текста, должно осуществляться прикладной функцией gap. Она должна обнаруживать во входном буфере inbuf структуры FORMBUF первый символ, отличный от символов пробела и табуляции, и возвращать его код. Таким образом прикладная функция gap должна возвращать код '\n' для пустой строки входного текста или любое другое значение в противном случае. Пропуск начальных пробелов и табуляций во входном буфере должен быть реализован с помощью библиотечной
функции strspn.
Вызов рассмотренных прикладных функций форматирования текста в сочетании с обращением к перегруженным операциям ввода-вывода getbuf и putbuf должна обеспечивать управляющая функция format. Ее исходный код образуют два цикла, итерации которых должны обеспечивать выполнение алгоритма форматирования текста.
Внешний цикл должен обеспечивать получение очередной строки исходного текста во входной буфер inbuf структуры FORMBUF путем вызова прикладной функции getbuf и распознавание пустой строки в конце абзаца текста по коду возврата прикладной функции gap. При обнаружении пустой входной строки должны быть вызваны прикладная функция trailer с целью обработки конца текущего абзаца текста и прикладная функция putbuf для записи его последней строки, полученной во выходном буфере outbuf структуры FORMBUF в результирующий типографический текст. Итерации внешнего цикла должны продолжаться пока при очередном вызове прикладной функции getbuf не будет обнаружен конец входного потока. После завершения внешнего цикла должен быть предусмотрен вызов прикладных функций trailer и putbuf, соответственно, для формирования и записи последней строки текста.
Внутренний цикл должен выполняться для обработки содержимого входного буфера inbuf структуры FORMBUF с целью формирования и записи строк абзаца результирующего типографического текста. В блоке внутреннего цикла управляющей функции format должен быть реализован вызов прикладных функций getword, chklimit, expander, putword и putbuf в соответствии с алгоритмом форматирования абзацев текста. Итерации внутреннего цикла должны продолжаться пока не будут обработаны все слова входного буфера.
Каждая итерация внутреннего цикла должна начинаться обращением к прикладной функции getword, чтобы получить очередное слово из входного буфера inbuf и сохранить его адрес в поле word структуры FORMBUF. Затем необходимо вызвать прикладную функцию chklimit для проверки возможности дополнить очередным словом, полученным по адресу word, рабочий буфер wordbuf структуры FORMBUF. Если ее код возврата больше нуля, то перед добавлением полученного слова следует выполнить процедуру выравнивания слов, накопленных в рабочем буфере слов workbuf, используя прикладную функцию expander, и записать сформированную в выходном буфере outbuf структуры FORMBUF строку в результирующий типографический текст с помощью прикладной функции putbuf. При этом рабочий буфер слов workbuf будет очищен и готов для размещения текущего слова, адресованного полем word структуры FORMBUF. Итерацию внутреннего цикла должен завершать вызов функции putword для добавления текущего слова в рабочий буфер слов workbuf.
Основная функция
Основная функция main должна обеспечивать управление вызовом прикладных функций программы BOUND и определение автоматической переменной fbuf для адресации структуры FORMBUF. Через ее формальные параметры в программу BOUND должны передаваться размер и адрес массива аргументов командной строки вызова программы BOUND. Основная функция main должна возвращать целочисленный код, который идентифицирует характер завершения программы BOUND. При этом нулевой код возврата должен соответствовать успешному завершению программы BOUND, а ненулевой код возврата должен обозначать ее аварийное завершение, когда процесс форматирования исходного текста не может быть выполнен по тем или иным причинам. Соответствующий код возврата должен передаваться через оператор return.
В начале операционного блока основной функции main, после определения структуры FORMBUF, должно быть специфицировано обращение к прикладным функциям gramma, usage и convert, которые должны обеспечивать разбор аргументов командной строки вызова программы BOUND. В случае его успеха в основной функции main должна вызываться прикладная функция textopen, которая открывает потоки чтения-записи файлов, содержащих исходный и результирующий форматированный текст. Если указанные потоки не могут быть открыты в требуемых режимах, то выполнение программы BOUND должно быть аварийно завершено. Иначе управление передается прикладной функции format для выполнения процедуры форматирования текста. После возврата из функции format должна вызываться прикладная функция closetext, чтобы закрыть потоки ввода-вывода, открытые прикладной функцией textopen. Основную функцию main должен завершать оператор return для возврата нулевого кода в операционную среду вызова программы BOUND.
Компановка программы
Исходный код программы BOUND целесообразно разделить по функциональному признаку на пять текстовых файлов: parse.c, inount.c, forma.c, bound.c и bound.h, которые должны быть сосредоточены в любом доступном каталоге файловой системы среды разработки. Все перечисленные файлы могут быть подготовлены любым текстовым редактором операционной среды разработки программы BOUND.
В файле parse.c следует специфицировать исходный код прикладных функций разбора аргументов командной строки вызова программы BOUND. В файле inout.c целесообразно сосредоточить исходный код прикладных функций, которые обеспечивают перегрузку операций ввода-вывода потоков текстовой информации в процессе ее форматирования. В файле forma.c рекомендуется разместить исходный код прикладных функций, непосредственно реализующих алгоритм форматирования текста. Файл bound.c должен содержать исходный код основной функции main программы BOUND. Заголовочный файл bound.h предназначается для декларации структуры FORMBUF и объявления прототипа для всех прикладных функций программы BOUND. Его содержимое должно быть включено во все остальные файлы с исходными текстами программы BOUND
директивой #include. Аналогичным образом должны подключены необходимые стандартные заголовочные файлы системы программирования C.
Трансляцию исходного кода и компоновку выполняемого модуля программы BOUND должны обеспечивать инструментальные средства компилирующей системы программирования C. В OS UNIX формирование выполняемого модуля программы BOUND может быть реализовано, например, следующей командной строкой:
$ cc -o bound bound.c parse.c inount.c forma.c
При отсутствии ошибок компиляции и компоновки результатом этой команды является выполняемый файл bound, который образуется в текущем каталоге файловой системы OS UNIX.
Отладка программы
С целью отладки программы BOUND рекомендуется подготовить текстовый файл, содержащий произвольный текст, разделенный на абзацы, и сохранить его под именем, например, bound.src в текущем каталоге файловой системы. Подготовленный файл с исходным текстом нужно отформатировать программой BOUND, чтобы получить результирующие файлы, содержащие типографический текст с различной длиной строки.
В частности, для того чтобы получить результирующий текст, где строки абзацев выровнены по правой границе и имеют длину 72 символа, нужно выполнить следующую команду:
$ bound -o bound.72 -i bound.src -l 72
В результате выполнения этой команды должен образоваться выходной файл bound.72, содержащий типографический текст с требуемой длиной строк абзацев. Аналогичная команда может быть выполнена для построения файла, например, bound.64 с длиной строк абзацев типографического текста, равной 64 символа. Полученные результаты могут быть просмотрены любым текстовым редактором операционной среды разработки программы BOUND.
Контрольные задания
1. Сопоставить результаты обработки текстового файла программой BOUND и стандартной командой fmt из дистрибутива OS Linux.
2. Модифицировать программу BOUND, используя для разбора аргументов командной строки ее вызова стандартную библиотечную функцию getopt из системы программирования C.
3. Усовершенствовать программу BOUND таким образом, чтобы исключить вероятность появления колонок абзацев типографического текста, которые состоят только из символов пробелов.
4. Изменить программу BOUND для применения в режиме фильтра, который получает исходный неформатированный текст из потока стандартного ввода и отображает результирующий типографический текст в потоке стандартного вывода.
Список литературы
1. Г. Шилд Полный справочник по C. - М.: Вильямс, 2002 г.
2. С. Прата Язык программирования C. - М.: DiaSoft, 2002 г.
3. Т.М. Волосатова, С.В. Родионов, М.В. Филиппов Прикладное программирование в стандарте ANSI C. - М.: МГТУ, 2003 г.
4. Б. Керниган, Ф. Плоджер Инструментальные средства программирования на языке Паскаль. - М.: Радио и связь, 1985 г