Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3 проги на си ОАИП 2 сем 2009 вмсис / отчёт УЧЕБНАЯ ПРАКТИКА.doc
Скачиваний:
17
Добавлен:
15.06.2014
Размер:
1.59 Mб
Скачать

5 Код программы

#include<stdio.h>

#include<conio.h>

#include<stdlib.h>

#include<locale.h>

#define m 60 //максимальная длина строки

void in(char **, int ); //функция ввода

void lastw(char **,int ); //функция переноса последего слова в конец строки

void work(char **, int); //функция выбора промежутков

void perenos(int , char **, int , int , int , int , int ); //перенос слов

void out(char **,int ); //функция вывода

void main()

{

int i,z=0;

char ch;

int n; //максимальное кол-во строк

char **text; //массив строк (текст)

do

{

do

{

system("cls");

fflush(stdin);

setlocale(LC_ALL,".ACP");

printf("Ширина стрницы = %d",m);

printf("\n//постановка абзаца - знак процента\n//ручной переход на следующую строку - Enter\n//закончить ввод - Esc");

printf("\nВведите число строк в тексте --> ");

setlocale(LC_ALL,".OCP");

z=scanf("%d",&n); //ввод числа строк в тексте

} while(!z);

if(!(text=(char**)calloc(n,sizeof(char*)))) //выделение памяти

{

setlocale(LC_ALL,".ACP");

printf("\nНет памяти");

setlocale(LC_ALL,".OCP");

getch();

}

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

if(!(*(text+i)=(char*)calloc(m+1,sizeof(char))))

{

setlocale(LC_ALL,".ACP");

printf("\nНет памяти");

setlocale(LC_ALL,".OCP");

getch();

}

in(text,n); //функция ввода

lastw(text,n); //функция переноса последего слова в конец строки

work(text,n); //функция выбора промежутков

out(text,n); //функция вывода

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

free(*(text+i)); //освобождение памяти

setlocale(LC_ALL,".ACP");

printf("\nНажмите 'Esc' чтобы выйти\n");

setlocale(LC_ALL,".OCP");

ch=getch();

}while(ch!=27);

}

void in(char **text, int n)

{

int i,j=0,k;

char ch=0;

int abz=0;

fflush(stdin);

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

{

for(j=0;j<m;j++)

{

if(abz==1)

for(j=0;j<4;j++)

{

*(*(text+i)+j)=' ';

printf(" ");

}

ch=getch();

putchar(ch); //для отображения русских символов

*(*(text+i)+j)=ch;

if(ch=='%') //абзац (если нажат '%')

for(j=j+1;j<m;j++) //заполнение пробелами до конца

{

*(*(text+i)+j)=32;

abz=1;

}

else abz=0;

if(ch==13) //переход на новую строку вручную ('Enter')

for(j=j;j<m;j++) //заполнение пробелами до конца строки

*(*(text+i)+j)=32;

if(ch==27) //если нажат 'Esc' то прекратить ввод

{

for(j=j;j<m;j++) //заполнение пробелами до конца строки

*(*(text+i)+j)=32;

i=n-1; // для выхода из цикла for(i=0;i<n;i++)

break;

}

}

printf("\n");

}

}

void lastw(char **text, int n) //функция переноса последего слова в конец строки

{

int i,j=0,k=0;

int e; //расстояние от конца последнего слова до конца строки

int es; //длина последнего слова в строке

char *last; //указатель на последнее слово

for(i=0;i<n-1;i++) //перемещение последнего слова в конец строки

{

e=0;

es=0;

for(j=m-1;j>=0;j--)

{

if(*(*(text+i)+j)=='%') //если абзац то не переносить слово

break;

if(*(*(text+i)+j)==' ')

{

e++; //счёткик расстояния от конца последнего слова до конца строки

if(*(*(text+i)+j-1)!=' ')

continue;

}

if(*(*(text+i)+j)!=' ')

{

es++; //счёткик длины последнего слова

if(*(*(text+i)+j-1)==' ')

break;

}

}

last=(char*)calloc(es,sizeof(int)); //выделение памяти для last

for(j=m-1-e,k=es-1 ; j>=m-e-es,k>=0 ; j--,k--) //начинаем с конца последнего слова

*(last+k)=*(*(text+i)+j); //занесение в новую строку

for(j=m-es-e;j<m-es;j++)

*(*(text+i)+j)=' '; //заполнение пробелами области до последнего слова

for(j=m-es,k=0 ; j<m,k<es ; j++,k++)

*(*(text+i)+j)=*(last+k); //пернос последнего слова в конец

}

}

void work(char **text, int n)

{

int i,j=0;

int p; //счётчик пробелов

int g; //счётчик групп пробелов

int h; //результат деления

int o; //остаток

int f; //длина первого слова

int l; //длина последнего слова

int ex; //для абзаца

for(i=0;i<n-1;i++)

{

h=0,o=0,f=0,l=0,p=0,g=0,ex=0; //обнуление для других строк

if(*(*(text+i)+0)==' ') //esli pervie probely

for(j=0;j<m;j++)

if(*(*(text+i)+j)==' ')

{

f++;

if(*(*(text+i)+j+1)!=' ')

break;

}

for(j=f;j<m;j++)

{

if(*(*(text+i)+j)=='%') //если абзац то не переносить

{

*(*(text+i)+j)=' ';

ex++;

break;

}

if(*(*(text+i)+j)==' ') //считаем кол-во пробелов

{

p++;

if(*(*(text+i)+j+1)!=' ') //считаем кол-во групп пробелов

g++;

}

}

if(ex!=0) //если абзац

continue;

for(j=f;j<m;j++)

if(*(*(text+i)+j)!=' ') //считаем длину первого слова

{

f++;

if(*(*(text+i)+j+1)==' ')

break;

}

for(j=m-1;j>=0;j--)

if(*(*(text+i)+j)!=' ') //считаем длину последнего слова

{

l++;

if(*(*(text+i)+j-1)==' ')

break;

}

if(g==0 || g==1 || (p-g)==0 || (p-g)==1) //если не надо перенос

break;

h=p/g; //ровное число пробелов

o=p%g; //лишние пробелы (остаток от деления)

perenos(i,text,h,o,g,f,l); //рекурсивная функция переноса слов

}

}

void perenos(int i, char **text, int h, int o, int g, int f, int l)

{

int j;

int ff=0; //расстояние от начала границы до след-го слова

int ll=0; //расстояние от конца слова до првой границы

int adin=0; //для переноса слова к границе (его длина минус один)

int hh=0; //чтобы промежутки отличались только на 1

static int rec=0; //число рекурсий

rec++;

if(rec>g) //если нужное кол-во слов пренесено

return; //то выход из рекурсивной функции

if(o>0) //если остались лишние пробелы

hh=h+1;

else hh=h;

o--; //убавляем для рекурсии

for(j=f;j<m-l;j++)

if(*(*(text+i)+j)==' ')

{

ff++; //считаем расстояние от начала до след-го слова

if(*(*(text+i)+j+1)!=' ')

break;

}

for(j=m-l-1;j>=f;j--)

if(*(*(text+i)+j)==' ')

{

ll++; //считаем расстояние от конца до след-го слова

if(*(*(text+i)+j-1)!=' ')

break;

}

if(ll>=ff) //перенос к правому краю

{

for(j=m-l-1;j>=f+ff;j--)

if(*(*(text+i)+j)!=' ')

{

*(*(text+i)+m-l-1-hh-adin)=*(*(text+i)+j);

if(*(*(text+i)+j-1)==' ')

break;

adin++;

}

for(j=j;j<m-l-hh-adin-1;j++)

*(*(text+i)+j)=' '; //заполнение пробелами

perenos(i,text,h,o,g,f,l+hh+adin+1);

}

else //перенос к левому краю

{

for(j=f;j<m-l-ll;j++)

if(*(*(text+i)+j)!=' ')

{

*(*(text+i)+f+hh+adin)=*(*(text+i)+j);

if(*(*(text+i)+j+1)==' ')

break;

adin++;

}

for(j=j;j>f+hh+adin;j--)

*(*(text+i)+j)=' '; //заполнение пробелами

perenos(i,text,h,o,g,f+hh+adin+1,l);

}

rec=0; //чтобы не сбить счётчик рекурсий

}

void out(char **text,int n) //функция вывода

{

int i,j;

setlocale(LC_ALL,".ACP");

printf("\nВведённый текст:\n");

setlocale(LC_ALL,".OCP");

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

{

for(j=0;j<m;j++)

putchar(*(*(text+i)+j)); //посимвольный вывод

printf("\n");

}

}