Программирование >>  Динамические структуры данных 

1 ... 21 22 23 [ 24 ] 25 26 27 ... 38


Ниже приведены тексты очень простой многофайловой программы, в которой определены типы данных Точка (структура Point в файле Point.h) и Прямоугольник (структура Rect в файле Rect. h). Поскольку второй тип данных определяется через первый, в файле Rect. h имеется директива #i ncl ude Poi nt. h . В основном модуле main.cpp просто создается объект типа Прямоугольник * и выводятся координаты его левого верхнего и правого нижнего углов. В основном модуле используются как функции из модуля Point .срр, так и функции из модуля Rect. срр, поэтому в него включены оба заголовочных файла Poi nt. h и Rect. h. Но после обработки этих директив препроцессором окажется, что структура Poi nt определена дважды. В результате компилятор выдаст сообщение об ошибке наподобие следующего: еггог...: Point: struct type redefinition .

тип III Файл Point.h llllllllll II Объявления типов struct Point {

int x:

int y:

Прототипы функций

void SetXY(Point& point, int x. int y):

int GetX(Points point):

int GetY(Points point):

llllllllll Файл Rect.h llllllllll . #include Point.h Объявления типов struct Rect {

Point leftTop:

Point rightBottom:

Прототипы функций

void SetLTRB(Rect& rect. Point It. Point rb): void GetLT(Rect& rect. Point& It): void GetRB(Rect& rect. Pointb rb):

llllllllll Файл Point.срр llllllllll #incl ude Point.h

void SetXY(Point& point, int x. int y) { point.X = x: point.у = у:

int GetX(Points point) { return point.x:

Под объектом мы здесь понимаем переменную типа struct.

int GetY(Points point) { return point.у:

llllllllll Файл Rect.срр llllllllll #include Rect.h

void SetLTRB(Rect& rect. Point It. Point rb) { rect.leftTop - It: rect.rightBottom - rb:

void GetLT(Rect& rect. Points It) { It = rect.leftTop:

void GetRB(Rect& rect. Point& rb) { rb - rect.rightBottom:

#include <stdio.h>

#include Point.h #include Rect.h

llllllllll Файл Main.cpp llllllllll int main(){

Point ptl. pt2. It. rb:

Rect recti:

SetXY(ptl. 2. 5): SetXY(pt2. 10. 14):

SetLTRB(recti, ptl. pt2): GetLT(recti. It): GetRB(recti, rb):

printf( rect.It.x - Xd. rect.lt.y = Xd\n . It.x. It.y): printf( rect.rb.X - W. rect.rb.y - XdXn . rb.x, rb.y): return 0:

Каков выход из этой ситуации? Бьерн Страуструп рекомендует использовать так называемые стражи включения, и этот способ нашел широкое применение. Он состоит в следующем: чтобы предотвратить повторное включение заголовочных файлов, содержимое каждого . h-файладолжно находиться между директивами условной компиляции #i f ndef и #endi f, как описано ниже:

fifndef FILENAME Н



#define FILENAME H

/* содержимое заголовочного файла */

#endif /* FILENAME H */ Применительно к нашему примеру файл Point.h должен содержать следующий текст:

Файл Point.h inillllll #ifndef POINT H #define POINT H Объявления типов struct Point {

int x:

int y:

Прототипы функций

void SetXYCPoints point, int x. int y):

int GetX(Points point):

int GetY(Points point);

#endif /* POINT H */ Рекомендуем вам проверить рассмотренный пример на вашем компиляторе.

Задача 7.7. Многофайловый проект - форматирование текста

Написать программу форматирования текста, читаемого из файла unfomt.txt и состоящего из строк ограниченной длины. Слова в строке разделены произвольным количеством пробелов. Программа должна читать входной файл по строкам, форматировать каждую строку и выводить результат в выходной файл formatd. txt. Форматирование заключается в выравнивании границ текста слева и справа путем равномерного распределения пробелов между соседними словами, а также в отступе с левой стороны страницы на margin позиций, то есть результирующий текст должен находиться в позициях margin + 1 margin + maxTJine. Кроме этого, программа должна подсчитать общее количество слов в тексте. На примере этой задачи мы показываем технологию разработки многофайловых проектов.

Алгоритм решения задачи не представляет особой сложности:

1. Открыть входной файл.

2. Читать файл построчно в текстовый буфер line, попутно удаляя возможные пробелы в начале строки (до первого слова).

3. Для каждой строки 1 i ne выполнить следующие действия:

Вычислить величину интервала (количество пробелов), которую необходимо обеспечить между соседними словами для равномерного распределения слов в пределах строки.

Вывести каждое слово из строки 1 i пе в выходной файл, вставляя между словами необходимое количество пробелов и одновременно увеличивая счетчик слов на единицу.

4. После обработки последней строки входного файла вывести на экран значение

счетчика слов и закрыть выходной файл. Разбиение на подзадачи.

В результате детализации описанного алгоритма определяем спецификации нужных нам функций:

□ void Def Inter (const char* pi ine. int 8 basejnt. int & addjnt. int & inter) определяет для строки, на которую указывает pline, количество межсловных промежутков inter, требуемую величину основного интервала baseint для каждого промежутка (количество пробелов) и величину дополнительного интервала addi nt, определяемую как остаток от деления общего количества пробелов в строке на количество межсловных промежутков; последняя величина должна быть равномерно распределена путем добавления одного пробела в каждый из первых addint промежутков;

□ void GetLine (FILE* finp. char* pline) читает очередную строку из входного файла в массив символов с адресом р1 ine, ликвидируя при этом пробелы в начале строки;

□ void Put Interval (FILE* fout, const int к) выводит очередной интервал, состоящий из к пробелов;

□ int PutWord (FILE* fout. const char* pline. const int startpos) выводит очередное слово в выходной файл, начиная с позиции startpos текущей строки р1 ine; возвращает номер позиции в строке pline, следующей за последним переданным символом, или О - если достигнут конец строки;

□ int SearchNextWord (const char* pline. const int curpos) возвращает номер позиции, с которой начинается следующее слово в строке р1 ine, или О, если достигнут конец строки (поиск начинается с позиции curpos).

Разбиение на модули.

Наша программа будет располагаться в двух исходных файлах: taslc7 7. срр - с функцией mai п, edit .срр - с реализацией перечисленных выше функций, а также заголовочный файл edit .h с интерфейсом этих функций. Ниже приводится содержимое этих файлов.

/

Файл Task7 7.cpp

#include <stdio.h>

finclude <string.h>

#include <stdlib.h>

#include edit.h

Глобальные переменные const int maxljine = 63: const int margin = 5:



int main(){

FILE* finp: FILE* fout:

char line[maxl line +1]:

int b i. aj. start, next, inter:

int nword = 0:

printfC Работает программа Task7 7.\n ): if(!(finp- fopen( unformt.txt . r ))) { printf( Файл urformt.txt не найден.\n ): exit(O):

printf( Читается файл unformt.txt.Vn ): if(!(fout - fopen( formatd.txt . w ))) { printf( Файл formatd.txt не создан.\n ): exit(O):

printf( Выполняется запись в файл formatd.txt.\n ):

while(GetLine(finp. line)) { Deflnterdine. b i. a i. inter): PutInterval(fout. margin): next = PutWordCfout. line. 0. nword):

for (int i = 0: i < inter: i++) { start = SearchNextWorddine. next): PutInterval(fout. b i): if (a i) { aJ--: PutlntervaUfout. 1): } next - PutWord(fout. line, start, nword): if (!next) break:

fprintf(fout. \n ):

printf( \nKoличecтвo слов - XdVn . nword): fclose(fout):

printf( Работа завершена An ): return 0:

ll/lll/ll/IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIUinnnilll II Файл Edit.h

Прототипы функций

void DefInter(corst char* pline. int& basejnt..int& addjnt.

int& inter): int GetLine(FILE*. char*): void PutlntervaKFILE*. const int):

int PutWord(FILE*. const char*, const int. int&): int SearchNextWord(const char*, const int):

Глобальные переменные extern const int maxljine:

llllllllllllllllllllllllillllllllllllllllllllllllllllllltll II Файл Edit.срр

#include <stdio.h> #include <string.h> #include edit.h

int GetLine(FILE* finp. char* pline) ( int i = 0: char c:

while ((c - fgetc(finp)) ) i++:

if(c EOF) return 0:

fseek(finp. -1. SEEK CUR):

fgets (pi ine. maxljine - i + 1. finp):

pline[strlen(pline) - 1] - 0:

return 1;

int SearchNextWord(const char* pline. const int curpos) { int i = curpos: while(pline[i] !-){

if (plineCi] - Xn ) return 0:

i++:

while (plineCi] -&& pline[i + 1] -= * *) i++; return i + 1:

void DefInter(const char* pline. int& basejnt. int& addjnt. int& inter) { int к = 0. end:

end = strlen(pline) - 1:

while ((plineCend] = ) (plineCend] = Vn) (pline[end] Xr)) end--:

inter = 0:



1 ... 21 22 23 [ 24 ] 25 26 27 ... 38

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика