Выровнять текст по ширине 60 символов - C (СИ)
Формулировка задачи:
Необходимо выровнять строку на экране по ширине, равномерно вставляя пробелы между словами, таким образом, чтобы в каждой строке было по 60 символов и строка обязательно заканчивалась знаком препинания или пробелом.
Есть не рабочий код, прошу помочь.
#include <stdio.h>
#include <string.h>
#include <windows.h>
void main()
{
char str[200], str1[70];
char *start=str1, *p;
char raz[] = " .,?!;:-\0";
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
printf("Введите текст:\n");
gets_s(str);
int i , z, j, k, a=0, kp;
while (strlen(str) > 59)//пока длина строки больше 59
{
i = 59;//ширина текста
kp = 0;//количество пробелов
str1 == " ";//очищение строки
while (strchr(raz, str[i]) == NULL);//пока не найдем разделитель
{
i--;//двигаемся к началу
kp++;
}
strncpy(str1, str, i);//копируем 59 символов в новую строку
str1[i + 1] = '\0';//заканчиваем новую строку
strcpy(str, str + (i + 1));//копируем хвост в начало старой строки
while (strlen(str1) < 60)//работаем с новой строкой
{
z = 2;
while (1)//пока не достигнем конца строки
{
p = strchr(start, ' ');//первый пробел от начала строки
if (p == NULL)//если пробела нет
{
z++;//количество пробелов между словами
}
j = p - str1;//позиция пробела
for (k = strlen(str1); k > j; k--)//сдвиг
str1[k] = str1[k - 1];//сдвигаем символ на предыдущий
kp--;//уменьшаем количество пробелов
if (kp == 0)//если пробелы закончились
break;//прерываем цикл
else//если пробелы не закончились
start = p + z;//начинаем с последнего пробела в начале строки
}
puts(str1);
}
}
system("pause");
}Решение задачи: «Выровнять текст по ширине 60 символов»
textual
Листинг программы
#include <stdio.h>
#include <string.h>
#define N 60
void rightAlignment(char* );
int main()
{
char s[] = "What can you say about a twenty-five-year-old girl who died?That she was beautiful.And brilliant.That "
"she loved Mozart and Bach.And the Beatles.And me.Once,when she specifically jumped me with those musical"
" types, I asked her what the order was, and she replied, smiling.At the time I smiled too. But now I sit"
" and wonder whether she was listing me by my first name - in which case I would trail Mozart - or by my"
" last name, in which case I would edge in there between Bach and the Beatles.Either way I don't come first,"
" which for some stupid reason bothers hell out of me,having grown up with the notion that I always had to"
" be number one.Family heritage,don't you know?";
rightAlignment(s);
return 0;
}
void rightAlignment(char* str)
{
char *first, *last, *end;
char delim[] = ",.; :!?";
int i = 0, flag = 0, count = 0, finish = 0;
end = &str[strlen(str)];
last = first = str;
while(!finish){
last += N;
if(last >= end){//если кончился текст
last = end - 1;
finish = 1;
}
flag = 0;
while(!flag && !finish){
for(i = 0; delim[i]; i++)
if(*last == delim[i]){//ищем конец строки
flag = 1;
break;
}
if(!flag)
last--;
}
char *last1 = last, *first1 = first;
int x = 0, y = 0, z = 0, q = 0, flag2 = 0;
x = N - (last - first);//сколько пробелов нужно добавить
count = 0;
if(x > 2){//если более двух то будем добавлять их равномерно в начало строки и после каждого слова,
while(first1 <= last1){ //но не после самого последнего
for(i = 0; delim[i]; i++){
if(*first1 == delim[i]){
y++; //считаем количество разделителей
break;
}
}
first1++;
}
if(x > y){//если пробелов больше чем слов
z = x / y;//вычисляем сколько пробелов подряд нужно вставлять
q = x % y;//не забываем про остаток
for(int j = z; j; j--){
putchar(' ');
}
}
else{
q = x;
if(q-- > 0)
putchar(' ');
}
while(first <= last){
flag2 = 0;
while(!flag2){
for(i = 0; delim[i]; i++)
if(*first == delim[i])
flag2 = 1;
putchar(*first++);//печатаем слово
}
if(z && first < last){
for(int j = z; j; j--)
putchar(' ');
}
if(q-- > 0)//остаток равномерно по одному вставляем после первых слов
putchar(' ');
}
}
else{//если пробелов требуется добавить 1 или 2
while(last - first + count++ < N)
putchar(' ');//просто добавляем их в начало строки
while(first <= last)
putchar(*first++);
}
putchar('\n');
}
}
Объяснение кода листинга программы
- Программа выравнивает текст по ширине 60 символов.
- Включаемые заголовочные файлы: stdio.h и string.h.
- Переменная N инициализируется значением 60, что соответствует ширине выравнивания.
- Функция rightAlignment() принимает на вход указатель на первый символ строки и выполняет выравнивание.
- В функции main() создается массив s[] со строкой, которую необходимо выровнять.
- Вызов функции rightAlignment(s); осуществляет выравнивание строки.
- Результат выравнивания выводится на экран с помощью функции printf().
- Если текст закончился, то есть достигнут конец строки, то переменная finish принимает значение 1.
- В цикле while(!finish) выполняется обработка строки до достижения конца или до добавления пробелов.
- В каждой итерации цикла вставляется пробел после каждого слова, разделенного символами из массива delim[].
- Если количество пробелов, которые необходимо добавить, больше двух, то они равномерно распределяются в начале строки и после каждого слова.
- Если количество пробелов меньше или равно двум, то они просто добавляются в начало строки.
- В конце каждой строки добавляется символ новой строки '\n'.