|
Программирование >> Разработка устойчивых систем
Пример обработки строк Если вы внимательно рассматривали примеры программ в книге, то наверняка обратили внимание на специальные маркеры в комментариях. Они используются программой Python для извлечения программного кода из файлов и построения make-файлов. Например, последовательность : в начале строки обозначает первую строку программы. За этими символами следует информация с именем файла, его местонахождением и флагом, который указывает, что профамму необходимо только откомпилировать (без построения исполняемого файла). Так, первая строка предыдущей профаммы содержит строку C03:IWCompare.cpp, означающую, что файл IWCompare.cpp извлекается из текстового файла в каталог СОЗ. Последняя строка фрагмента помечается прследовательностью /:~. Если в первой строке сразу же после двоеточия следует восклицательный знак, первая и последняя строки кода не выводятся в файл (для файлов, содержащих только данные). Возможности программы Python не ограничиваются простым извлечением кода. Если за именем файла следует маркер {Q}, то запись в make-файле настраивается на компиляцию исходного текста программы без его компоновки в исполняемый файл (в частности, так строится тестовая система в главе 2). Чтобы скомпоновать такой файл с другим исходным файлом, включите в исходный код исполняемой программы директиву {L}: {L} ../TestSuite/Test В этом разделе будет представлена утилита, которая извлекает из текста книги весь код (вы можете самостоятельно просмотреть и откомпилировать примеры ПрОфамм). Сохраните документ в текстовом формате (допустим, в файле TICV2.txt) и введите в командной строке следующую команду: С:> extractCode TICV2.txt /TheCode Команда читает текстовый файл TICV2.txt и сохраняет весь профаммный код в подкаталогах каталога ДИеСоЬе. Дерево каталогов будет выглядеть так: TheCode/ СОВ/ С01/ С02/ СОЗ/ С04/ С05/ Учтите, что некоторые версии Microsoft Word при сохранении в текстовом формате заменяют апострофы расширенным символом ASCII, что приводит к ошибкам компиляции. Мы понятия не имеем, почему это происходит. Просто замените символы апострофами вручную. assert(wfirst.compare(wsecond) == 0): assert(wfirst.find(h) =- 1): assert(wfirst.finder) -= 2): assert(wfirst.find(x) wstring::npos): } III:- К сожалению, некоторые компиляторы до сих пор не обладают полноценной поддержкой расширенных кодировок. СОб/ С07/ С08/ С09/ СЮ/ СИ/ TestSuite/ Файлы с исходными текстами примеров каждой главы находятся в соответствующем каталоге. А вот и сама программа: : C03:ExtractCode.cpp Извлечение программного кода из текста finclude <cassert> finclude <cstddef> finclude <cstdio> linclude <cstdlib> linclude <fstream> linclude <iostream> linclude <string> using namespace std: Унаследованный нестандартный заголовочный файл С для mkdirO lif defined ( GNUC ) defined( MSWERKS ) linclude <sys/stat.h> lei if defined( BORLANDC ) defined( MSC VER) II defined( DMC ) linclude <direct.h> lelse lerror Compiler not supported lendif Чтобы проверить, существует ли каталог, мы пытаемся открыть в нем новый файл для вывода, bool exists(string fname) { size t len - fname.lengthO: if(fnameClen-l] != 7 && fname[len-l] != W) fname.appendCV ): fname.append( ООО.tmp ); ofstream outf(fname.c str()): bool existFlag = outf: if (outf) { outf .closeO: retitove( f name. c str О): return existFlag: int main(int argc. char* argv[]) { Проверяем, указано ли имя входного файла if(argc == 1) { cerr usage: extractCode file Cdir]\n ; exit(EXIT FAILURE): Проверяем, существует ли входной файл ifstream inf(argv[l]); ifdinf) { cerr error opening file: argvCl] endl: exit(EXIT FAILURE): Проверяем наличие необязательного выходного каталога string rootC./ ): По умолчанию используется текущий каталог if(argc == 3) { Проверяем, существует ли выходной каталог root = argv[2]: if(!exists(root)) { cerr no such directory: root endl: exit(EXIT FAILURE): size t rootLen = root.lengthO: if(root[rootLen-l] != 7 && root[rootLen-1] != W) root.append( / ): Построчное чтение входного файла с проверкой маркеров начала и конца программных блоков string line: bool inCode = false: bool printDelims = true: ofstream outf: while (getline(inf. line)) { size t findDelim = line.find( /:- ): if(findDelim != string::npos) { Вывод последней строки и закрытие файла if (linCode) { cerr Lines out of order\n : exit(EXIT FAILURE): assert(outf): if (printDelims) outf line endl: outf.closeO: inCode = false: printDelims = true: } else { findDelim = line.find( : ): If(findDelim == 0) { Проверка директивы ! if(line[3] == !) { printDelims = false: ++findDelim: Чтобы пропустить ! при следующем поиске Извлечение имени подкаталога (если оно есть) size t startOfSubdir = line.find first not of( \t . findDelim+3): findDelim = line.find(:. startOfSubdir): if (findDelim == string::npos) { cerr missing filename information\n endl: exit(EXIT FAILURE): string subdir: if(findDelim > startOfSubdir) subdir = line.substr(StartOfSubdir. findDelim - startOfSubdir): Извлечение обязательного имени файла size t startOfFile = findDelim + 1: size t endOfFile = line.find first of( \t . startOfFile): if(endOfFile == startOfFile) I
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |