Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты в разделе

Коцюрбенко Алексей aka Жерар
Статус: Мастер-Эксперт
Рейтинг: 276
∙ повысить рейтинг »
CradleA
Статус: Профессионал
Рейтинг: 94
∙ повысить рейтинг »
Сергей Бендер
Статус: Профессионал
Рейтинг: 21
∙ повысить рейтинг »

∙ С / С++

Номер выпуска:1878
Дата выхода:02.07.2016, 11:51
Администратор рассылки:Андрей Кузнецов aka Dr_Andrew (Старший модератор)
Подписчиков / экспертов:19 / 14
Вопросов / ответов:1 / 1

Консультация # 189621: Уважаемые эксперты! Пожалуйста, ответьте на вопрос: не могли бы вы объяснить принцип работы данной функции выравнивания текста по ширине? ...

Консультация # 189621:

Уважаемые эксперты! Пожалуйста, ответьте на вопрос:

не могли бы вы объяснить принцип работы данной функции выравнивания текста по ширине?

Дата отправки: 27.06.2016, 11:35
Вопрос задал: Александр (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, Александр!
Смотрите комментарии...
#include <iostream>
 
using namespace std;

 //выравнивание по ширине
void printAligned(char* str, int width)
{
	if (strlen(str) == 0) 
	{
		cout << endl;			//если строка нулевой длины, то ничего не делаем 
		return;
	}

//создадим массив слов
	int wordBegin = 0;			//начало очередного слова в строке
	char** words = (char**) malloc(sizeof(char*)); //массив указателей на слова
	int wordsSize = 0;			//количество слов
	
	while (wordBegin < strlen(str))		//пока не кончилась строка
	{
		if (str[wordBegin] == ' ')		//ищем начало слова
		{
			wordBegin++; 
			continue; 
		}

		int wordLen = 1;		//найдем длину слова, имеем первый не пробел, т.е. длина = 1
								//пока не конец строки,и пока не пробел
		while (wordBegin + wordLen < strlen(str) && str[wordBegin + wordLen] != ' ')
		{
			wordLen++;			//считаем
		}
								//расширим массив слов на 1
		words = (char**) realloc(words, sizeof(char*) * (wordsSize + 1));
								//копируем в массив слово
		words[wordsSize] = strncpy((char*)malloc(sizeof(char)*(wordLen + 1)),str + wordBegin, wordLen);
								//с нулем
		words[wordsSize++][wordLen] = '\0';
		wordBegin += wordLen;	//перемещаем указатель в строке на слово
	}

//массив создан. Если нет ни одного слова - выходим
	if (wordsSize == 0)
	{
		cout << endl;
		return;
	}


//начинаем анализ на заполнение строки для вывода	
	for (int front = 0; front < wordsSize; )	//по всем словам, front - индекс текущего слова
	{
		while (strlen(words[front]) > width)	//если текущее слово больше длины выводимой строки!
		{										//то выведем его по кускам

												//скопируем часть слова, равную длине выводной строки
			char * toOut = strncpy((char*) malloc(sizeof(char) * (width + 1)),words[front], width);
												//остаток до конца слова
			char * rest = strcpy((char*) malloc(sizeof(char) * (strlen(words[front]) - width + 1)),words[front] + width);
			toOut[width] = '\0';				//закроем строки нулем
			rest[strlen(words[front]) - width + 1] = '\0';
			cout << toOut << endl;				//выведем начало слова (равную длине выводной строки!)
			free(words[front]);					//удалим длинное слово!
			free(toOut);						//удалим выведенное начало
			words[front] = rest;				//словом теперь будет остаток слова
		}										//и на повтор проверки длины строки!


//текущее слово помещается в выводимую строку, считаем слова, сколько их поместится в длину выводной строки
		int toPrint = 0;						//количество слов
		int toPrintW = 0;						//их общая длина
		for (int i = front; i != wordsSize; ++i)//от текущего слова и до конца 
		{										//добавление очередного слова (и пробела!) помещается в строку?
			if (toPrintW + strlen(words[i]) + toPrint <= width)
			{
				toPrintW += strlen(words[i]);	//считаем общую длину
				toPrint++;						//и слова
			} 
			else
			{
				break;							//очередное слово уже не помещается в чтроку
			}
		}

//выводим найденные слова
		if (toPrint > 1)						//больше одного слова?
		{
			//слова выравниваем по ширине, поэтому
			//посчитаем одинаковое количество пробелов между всеми слова
			// и количество промежутков, куда вставим дополнительно по одному пробелу
			int spaces = (width - toPrintW) / (toPrint - 1); //одинаковое количество между всеми словами
			int spaces2 = (width - toPrintW) % (toPrint - 1);//дополнительные пробелы, чтобы было выравнивание по ширине
			for (int j = 0; j < toPrint; ++j)	//по всем найденным словам
			{
				cout << words[front++];			//выводим слово

	
				if (j != toPrint - 1)			//кроме последнего
				{
					for (int s = 0; s < spaces; ++s) //выводим разделяющие пробелы
						cout << ' ';
					if (j < spaces2)			//и один дополнительный, если есть таковой
						cout << ' ';
				}
			}
		}
		else
		{
			cout << words[front++];				//одно слово просто выводим
		}
		cout << endl;							//конец строки
	}
}

char *text = "11111 2 33333 44444 5555 6666 777777777777777777777 8888888888 9999999999999999999999999999999 0000 a sa d f g\r\n";
		
int main()
{
	printAligned(text, 20);
	return 0;
}

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 29.06.2016, 11:49
Рейтинг ответа:

НЕ одобряю +1 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!


В избранное