Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Листинг 7.8






 

///////////////////////////////////////////////////

// Файл Task7_7.cpp

#include < stdio.h>

#include < string.h>

#include < stdlib.h>

#include " edit.h"

 

// Глобальные переменные

const int maxljine = 63;

const int margin = 5;

 

int main()

{

FILE* finp;

FILE* tout;

char line[maxl_line + 1];

int b i, a i, start, next, inter;

int nword = 0;

printf(" Работает программа Task7 7.\n");

if(! (finp = fopen(" unformt.txt", ”W”)))

{

printf(" Файл unformt.txt не найден.\n”);

exit(0);

}

printf(" Читается файл unformt.txt \n");

if(! (fout = fopen(“formatd.txt", " w")))

{

printf(" Фaйл formatd.txt не создан.\n”);

exit(O);

}

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

while(GetLine(finp. line))

{

DefInter (line, b i, a_i, inter);

PutInterval(fout, margin);

next = PutWord(fout, line, start, nword);

for (int i = 0; i < inter; i++)

{

start = SearchNextWord(line. next);

Putlnterval(fout.. b i);

if (a j) { a i--; Putlnterval(fout. 1);

}

next = PutWord(fout. line, start, nword);

if (! next) break;

}

fprintf(fout. “\n");

}

printf (“\nКоличество слов - %d\n”, nword);

fclose(fout);

printf(" Работа завершена \n");

return 0;

///////////////////////////////////////////////////

// Файл Edit.h

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

void DefInter(const char* pline, Int& base int, int& add int,

int& inter);

int GetLine(FILE*. char*);

void Putlnterval(FILE*. const int);

int PutWord(FILE*. const char*, const int. int&);

int SearchNextWord(const char*, const int);

 

// Глобальные переменные

extern const int maxl line;

///////////////////////////////////////////////////

// Файл Edit.cpp

#include < stdio.h>

#include < string.h>

#include " edlt.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(pline. Maxl line -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 (pline[i] ==; \n”) return 0:

i++;

}

while (pline[i] == ’ ‘& & pline[i + 1] == ' ') i++;

return i + 1;

}

 

void DefInter(const char* pline. int& base int. int& add int. int& inter)

{

int к = 0, end;

end = strlen(pline) - 1;

while ((pline[end] == ' ') || (pline[end] == ’\n') || (pline[end] == '\r')) end--;

inter = 0;

 

for (unsigned int i= 0; i < end; i++)

{

if (pline[i] == ' ')

{

if (pline[i + 1]! = ' ') inter++;

}

}

int blank amount * к + maxl line - end;

if (! k)

{

base int = 0;

add int = 0;

}

else

{

base int = blank amount / inter;

addjnt = blank amount % inter;

}

return;

}

 

int PutWord (FILE* fout, const char* pline, const int startpos, int& n)

{

int i = startpos;

char c;

n++;

while ((c - pline[i++])! =' ‘)

{

fprintf(fout, " %c", c);

if ((c = '\n'> || (c == '\0'))

{

i = 0;

break;

}

}

return i - 1;

void Putlnterval(FILE* fout, const int k)

{

for (int i=0; i< k; i++) fprintf(fout, " );

return;

}

}

///////////////////////////////////////////////////

 

Имена функций мы здесь записали (для разнообразия) в стиле Microsoft, с использованием прописных букв для выделения осмысленных частей имени. Константу maxl 1 пе следует задавать большей, чем максимальная длина строки исходного файла. В качестве самостоятельного упражнения измените про­грамму так, чтобы можно было форматировать текст и в более узкую колонку, чем в исходном файле.

Перегрузка функций. Перегрузкой функций называется использование нескольких функций с одним и тем же именем, но с различными списками параметров. Перегруженные функции должны отличаться друг от друга либо типом хотя бы одного параметра, либо ко­личеством параметров, либо и тем и другим одновременно. Перегрузка является видом полиморфизма и применяется в тех случаях, когда одно и то же по смыслу действие реализуется по-разному для различных типов или структур данных. Ком­пилятор сам определяет, какой именно вариант функции вызвать, руководствуясь списком аргументов.

Если же алгоритм не зависит от типа данных, лучше реализовать его не в виде группы перегруженных функций для различных типов, а в виде шаблона функ­ции. В этом случае компилятор сам сгенерирует текст функции для конкретных типов данных, с которыми выполняется вызов, и программисту не придется под­держивать несколько практически одинаковых функций.

Небольшие перегруженные функции удобно применять при отладке программ. Допустим, вам требуется промежуточная печать различного вида: в одном месте требуется выводить на экран структуру, в другом - пару целых величин с поясне­ниями или вещественный массив. Проще сразу оформить печать в виде функ­ций, например таких:

 

void print(char* str. const int i. const int j)

{

cout «str «' I' «oct «setw(4) «i «' |' «setw(4) «j «' |’ «endl;

}

 

void print(float mas[], const int n)

{

cout «" Массив: " «endl;

cout.setf(ios:: fixed);

cout.precision(2);

for (int i = 0; i < n; i++)

{

cout «mas[i] «" ";

if ((i + 1) % 4 == 0) cout «endl;

}

cout «endl;

}

 

void print(Man m)

{

cout.setf(i os:: fixed);

cout.precision(2);

cout «setw(40) «m.name «' ‘ «m.birth year < < ' ‘< < m.pay «endl;

}

 

В первой из этих функций на экран выводятся строка и два целых числа в восьме­ричной форме, разделенных вертикальными черточками для читаемости. Под каж­дое число отводится по 4 позиции (действие манипулятора setw распространяется только на ближайшее выводимое поле).

Во второй функции для вывода вещественных значений по четыре числа на строке задается вид вывода с фиксированной точкой и точностью в два десятичных знака после запятой. Для этого используются методы установки флагов setf, установки точности precision и константа f1xed, определенная в классе 1os. Точность касается только вещественных чисел, ее действие продолжается до следующей установки.

Третья функция выводит поля знакомой нам по шестому семинару структуры так, чтобы они не склеивались между собой. Манипулятор setw устанавливает ширину следующего за ним поля. Это приведет к тому, что фамилии будут выведены с от­ступом от края экрана. Вызов этих функций в программе может выглядеть, напри­мер, так:

 

print(" После цикла ", 1, п);

print(a. n);

print(m);

 

По имени функции сразу понятно, что она делает, кроме того, при необходимости вызов функции легче закомментировать или перенести в другое место, чем группу операторов печати. Конечно, промежуточная печать - не единственный метод от­ладки, но зато универсальный, потому что отладчик не всегда доступен.

При написании перегруженных функций основное внимание следует обращать на то, чтобы в процессе поиска нужного варианта функции по ее вызову не возникало неоднозначности.

Неоднозначность может возникнуть по нескольким причинам. Во-первых, из-за преобразований типов, которые компилятор выполняет по умолчанию. Смысл правил преобразования арифметических типов сводится к тому, что более короткие типы преобразуются в более длинные. Если соответствие между формальными параметрами и аргументами функции на одном и том же этапе может быть получено более чем одним спосо­бом, вызов считается неоднозначным и выдается сообщение об ошибке.

Неоднозначность может также возникнуть из-за параметров по умолчанию и ссы­лок. Рассмотрим создание перегруженных функций на примере.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.