
- •Введение
- •2 Условие задачи №1
- •3 Структура входных/выходных данных
- •4 Блок-схемы алгоритмов и алгоритмы по шагам
- •5 Код программы
- •6 Результаты работы программы
- •7 Условие задачи №2
- •8 Структура входных/выходных данных
- •9 Блок-схемы алгоритмов и алгоритмы по шагам
- •10 Код программы
- •11 Результаты работы программы
- •12 Условие задачи №3
- •13 Структура входных/выходных данных
- •14 Блок-схемы алгоритмов и алгоритмы по шагам
- •15 Код программы
- •16 Результаты работы программы
- •17 Заключение
- •18 Литература
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");
}
}