Выровнять текст по ширине 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');
    }
}

Объяснение кода листинга программы

  1. Программа выравнивает текст по ширине 60 символов.
  2. Включаемые заголовочные файлы: stdio.h и string.h.
  3. Переменная N инициализируется значением 60, что соответствует ширине выравнивания.
  4. Функция rightAlignment() принимает на вход указатель на первый символ строки и выполняет выравнивание.
  5. В функции main() создается массив s[] со строкой, которую необходимо выровнять.
  6. Вызов функции rightAlignment(s); осуществляет выравнивание строки.
  7. Результат выравнивания выводится на экран с помощью функции printf().
  8. Если текст закончился, то есть достигнут конец строки, то переменная finish принимает значение 1.
  9. В цикле while(!finish) выполняется обработка строки до достижения конца или до добавления пробелов.
  10. В каждой итерации цикла вставляется пробел после каждого слова, разделенного символами из массива delim[].
  11. Если количество пробелов, которые необходимо добавить, больше двух, то они равномерно распределяются в начале строки и после каждого слова.
  12. Если количество пробелов меньше или равно двум, то они просто добавляются в начало строки.
  13. В конце каждой строки добавляется символ новой строки '\n'.

Оцени полезность:

12   голосов , оценка 3.5 из 5
Похожие ответы