Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Модуль Forms 65535
ТЕХНОЛОГИИ ДОСТ... 62989
Имитационное мо... 58321
Реклама
Сейчас на сайте
Гостей: 6
На сайте нет зарегистрированных пользователей

Пользователей: 13,091
новичок: avegraf
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Лабораторная работа по динамическим спискам на Turbo Pascal (перемещение...
Моделирование работы аэропорта на GPSS + Пояснительная записка
Моделирование автовокзала + Отчет + Блок схема

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
Пример обработки текстовых файлов
В качестве примера обработки текстовых файлов напишем программу, которая реализует наиболее часто испбльзуемую функцию препроцессора — подключение файлов с помощью оператора #include.

Ограничим синтаксис оператора:
? оператор начинается с первой позиции строки;

Другой, значительно более эффективный способ копирования файлов мы рассмотрим позже.
• подключаемый файл всегда задается в формате «имя_файла»;
• имя файла отделяется от оператора #i n elude только одним пробелом.
Таким образом, непосредственно имя файла начинается в операторе всегда с 11-й позиции и продолжается до символа-кавычки. Подключаемый файл тоже может содержать операторы #include. Ограничение вложенности, очевидно, задается глобальной константой F0PEN_MAX, определяющей максимальное количество одновременно открытых файлов и определенной в заголовке <stdio. h>.
Итак, в результате получаем:
#include "имя_файла"



При подключении этот оператор записывается в результирующий файл как комментарий:
// #include имя_файла



После этой строки в результирующий файл записывается содержимое указанного файла. Если подключаемый файл не был открыт, то в результирующий файл записывается строка-комментарий:
// #include имя_файла --(Error! File not open!



Подключаемые файлы могут, вообще говоря, располагаться в различных каталогах, но мы для проверки работы программы соберем их все в нашем каталоге TextFlles. Файл, который надо обрабатывать первым, задается в командной строке. Если имя задано неверно, то программа завершает работу. Результирующий файл с именем result.files размещается в том же каталоге TextFiles. Текст программы представлен в листинге 14.5.

Листинг 14.5. Обработка оператора
#include
string NameFiles(const char *namefile) { string path = "c:/textfiles/"; return path+namefile;
}
bool isInclude(const string line)
{ if (line.substr(0,8) == "#includeM) return true;
else return false;
}
void includeFile(const char *namefile, ofstream &result) { static int countfiles = 0; ++countfiles;
if (countfiles > F0PEN_MAX) // файлов больше положенного?
{ сегг << "Too mani files is opened!" << endl; abort();
}
string line; // читаемая строка
const string tenminus = " ";
const string include = "#include "; string comment;
string name = NameFiles(namefile); // попное имя файла
ifstream in; // очередной входной файл
продолжение &
Листинг 14.5 {продолжение)
in. open (name. c__str ()); // открыли
if (in. is__open()) // если открылся
{ getline(in, line); ' while(!in.eof())
{ if (islnclude(line)) // если #include
{ char file[FILENAME_MAX];
int i = 0; // извлекаем имя файла из #include
while(line[i+10]! = "") { file[i]=line[i+10]; i++; }
file[i]=0; // завершающий ноль
comment = ,7/"+tenminus+include+file+tenminus;
result << comment << endl;
includeFile(file, result); // пошли внутрь
result <<"//-end \n";
}
else result << line << endl; '
getline(in, line);
}
in.closeO ;
}
else // формируем ошибочный комментарий
{ const string Error = "Error! -- File not open!";
comment = ,,//"+tenminus+include+namef ile+" -- "+Error+'\n';
result << comment;
}
}
int main(int argc. char *argv[])
{ ofstream result ("c:/textfiles/result.files");
if(!result.is_open()) // ошибка при открытии
{ cerr << "Error result file!" << endl; return 1;
}
includeFile(argv[l], result); result.close(); return 0;
}



Главная программа просто открывает результирующий файл и вызывает рекурсивную функцию обработки, передавая ей в качестве параметра имя файла из командной строки и поток-результат. Ошибки практически не обрабатываются, чтобы не отвлекаться от основной задачи — обработки файлов.
Основную работу выполняет рекурсивная функция includeFilе(), аргументом которой является имя обрабатываемого файла и поток-результат. Функция в начале считает количество открытых файлов — можно запрограммировать здесь более серьезную обработку ошибки (например, генерировать исключение). Если все в порядке, то формируется полное имя файла — работает вспомогательная функция NameFiles(). Далее файл открывается, и в цикле читаются строки файла. Если прочитана обычная строка, то она просто выводится в результирующий файл. Если же строка содержит оператор #i nclude (что определяет простая функция-предикат isIncludeO), то формируется и выводится строка-комментарий о включаемом файле и выполняется рекурсивный вызов. По окончании файла выводится дополнительная строка минусов со словом «end». Таким образом, включенный файл оказывается обрамленным двумя строками-комментариями. Если же при открытии файла возникли проблемы, то формируется строка-комментарий с ошибкой и функция завершает обработку текущего файла.
Создадим в каталоге TextFiles три небольших текстовых файла, a.txt, b.txt и d.txt:
• файл a.txt!:
ааааааааааааааа #include "b.txt" ааааааааааааааа



• файл b.txt:
bbbbbbbbbbbbbbbbbb #include "d.txt" bbbbbbbbbbbbbbbbbb #include "dd.txt" bbbbbbbbbbbbbbbbbb



• файл d.txt:
dddddddddddddddddd dddddddddddddddddd



Файл a.txt подключает файл b.txt, который, в свою очередь, подключает файл d.txt и ошибочный файл dd.txt. Результат работы нашей программы получается следующий:
ааааааааааааааа
// #include b.txt
bbbbbbbbbbbbbbbbbb
// #include d.txt dddddddddddddddddd dddddddddddddddddd
//-end -
bbbbbbbbbbbbbbbbbb
// #include dd.txt
// #include dd.txt -- Error! File not open!
//-end
bbbbbbbbbbbbbbbbbb
//-end-
ааааааааааааааа



Как видим, вложенные файлы обрабатываются совершенно правильно.
Собственно, если бы не нужно было формировать комментарий вокруг вложенного файла, функция includeFi 1е() была бы значительно короче (листинг 14.6).

Листинг 14.6. Функция inctudeFile()
void includeFile(const char *namefile, ofstream &result) { static int countfiles = 0;
++countfiles; // проверяем countfiles > F0PEN_MAX
if (countfiles > F0PEN_MAX)
{ cerr << "Too mani files is opened!" << endl; abort(); }



Листинг 14.6 (продолжение) string line;
string name = NameFiles(namefile); ifstream in; in.open(name.c_str()); if(in.is_open()) { getline(in, line); while(!in.eof())
{ if (islnclude(line)) includeFile(file, result);
else result << line << endl;
getline(in, line);
}
in.close();
}
else result << "Error! -- File not open!" << endl;
}



Этот вариант функции вполне можно использовать в «настоящем» препроцессоре.
Опубликовал Kest March 20 2014 15:04:10 · 0 Комментариев · 3165 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Иллюстрированный ...
THttpScan v4.1
Эффект лампы на р...
iChat v.7.0 Final...
начисление процен...
PHP: обучение на ...
Image Browser [Ис...
3d Tank [Исходник...
Мод "проверочный ...
C++ Стандартная б...
ActiveX в Delphi
JanComp
PDF
RAS
Алгоритмы шифрова...
Animation (Пример...
Определние размер...
Программирование ...
VksButton
Открытие Cd-ROM'a...

Топ загрузок
Приложение Клие... 100477
Delphi 7 Enterp... 87858
Converter AMR<-... 20082
GPSS World Stud... 13485
Borland C++Buil... 12053
Borland Delphi ... 8668
Turbo Pascal fo... 7048
Visual Studio 2... 5005
Калькулятор [Ис... 4906
FreeSMS v1.3.1 3545
Случайные статьи
Линия тренда
Видео – залог успе...
Генератор паролей
TokenVisionв качес...
Описание синтаксис...
Типизация перемен...
Структура наследов...
File components ma...
Теги Alt и Title в...
Классы профилей Ca...
ОЧЕРЕДИ В GPSS
Реализация механиз...
Windows Server - ...
Маршрутизаторы
Разработка собстве...
Процедура sort в с...
Объяснение
Когда наступает по...
Заключение
Формат блока YMODEM
Недвижимость в Чите
Алгоритм должен со...
Виртуальные сети
Экземпляры элемент...
Модуль Legacy
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?