Выровнять текст по ширине 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'.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д