Навигация
Главная
Поиск
Форум
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
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 14
На сайте нет зарегистрированных пользователей

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

Моделирование вычислительного центра на GPSS + Отчет + Блок схема
Моделирование процесса обеспечивающего надежность функционирования АСУ Т...
База данных электронного документооборота на Delphi + бд Intebase

Пример обработки текстовых файлов
В качестве примера обработки текстовых файлов напишем программу, которая реализует наиболее часто испбльзуемую функцию препроцессора — подключение файлов с помощью оператора #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 11:04:10 · 0 Комментариев · 5317 Прочтений · Для печати

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


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



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

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

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

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

Пароль



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

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

Случайные загрузки
PHP5. Профессиона...
Работа с картотеками
Gold Submitter II...
Zoom [Исходник на...
TsHintManager
Фундаментальные а...
Blobs [Исходник н...
CoolControls v3.0...
Averaging [Исходн...
Prolog Interprete...
Delphi на примерах
RbControls
Профессиональное ...
Degisy Data Acces...
Error mod
isoCanvas (Редакт...
TrayIcon
Язык программиров...
Delphi. Готовые а...
База предприятий ...

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97839
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14193
Borland Delphi ... 10293
Turbo Pascal fo... 7374
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Изменение звуковой...
Особенности практи...
уровня
Казино Jet
Создание и изменен...
Эта конфигурация н...
• Если RAS-сервер ...
Создание XHTML-при...
Управление темами ...
Введение в имитаци...
Что делать?
Команды предварите...
Защищайте доступно...
Encryption Pack мо...
Бизнес-модели инте...
Функции обработки ...
Оператор присваивания
Абстрактные типы д...
STORAGE (ПАМЯТЬ)
Разобрать список н...
Совместное примене...
ЧТО ТАКОЕ НОРМАЛИ...
Описание GPSS-прог...
DQTABLE (РАЗНОСТНА...
Виртуальные машины...
Статистика



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


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