UVa Problem 848 Fmt (Fmt 程序)

// Fmt (Fmt 程序)
// PC/UVa IDs: 110308/848, Popularity: C, Success rate: low Level: 2
// Verdict: Accepted
// Submission Date: 2011-05-22
// UVa Run Time: 0.008s
//
// 版权所有(C)2011,邱秋。metaphysis # yeah dot net
//
// 直接根据题意即可,有些繁琐。利用缓冲区的概念进行处理会相对的显得程序逻辑清晰一些。
	
#include <iostream>
	
using namespace std;
	
#define WIDTH 72	// 一行最大宽度
	
string buffer;	// 缓冲区。
	
// 判断某行是否是空行。
bool empty_line(string & line)
{
	return line.length() == 0;
}
	
// 判断该行是否是新行。
bool new_line(string & line)
{
	if (empty_line(line))
		return false;
	return line[0] == ' ';
}
	
// 移除行末尾的空格。
void trim_line(string & line)
{
	for (string::iterator it = line.end() - 1; it >= line.begin(); it--)
		if (*it == ' ')
			line.erase(it);
		else
			break;
}
	
// 处理缓冲区的内容。
void process_buffer()
{
	// 当缓存区有内容时输出。
	if (buffer.length() > 0)
	{
		if (buffer.length() <= WIDTH)
		{
			cout << buffer << endl;
			buffer.clear();
			return;
		}
	
		string line, word;
		string::iterator it = buffer.begin();
		string spaces;
	
		// 首先读入该行的前导空格。
		for (; it != buffer.end() && *it == ' '; spaces.append(1, ' '), it++)
			;
	
		// 将前导空格附加到输出行。
		line.append(spaces);
		spaces.clear();
	
		// 读取非空格字符直到遇到空格。
		for (; it != buffer.end() && *it != ' '; line.append(1, *it), it++)
			;
	
		// 判断是否需要输出该行。
		if (line.length() >= WIDTH)
		{
			cout << line << endl;
			line.clear();
		}
	
		// 输出行字符数小于或等于宽度 WIDTH,继续读取字符,直到缓冲区结束。
		while (line.length() <= WIDTH && it != buffer.end())
		{
			// 判断是否需要读入一个新的单词。
			if (word.length() == 0)
			{
				// 读入前导空格。
				for (; it != buffer.end() && *it == ' '; spaces.append(1, ' '), it++)
					;
				// 读入单词。
				for (; it != buffer.end() && *it != ' '; word.append(1, *it), it++)
					;
			}
	
			// 判断单词长度是否大于 WIDTH,决定是否占一行输出。
			if (word.length() >= WIDTH)
			{
				cout << line << endl << word << endl;
				line.clear();
				word.clear();
				spaces.clear();
			}
			else
			{
				// 若当前输出行为空,则需将前导空格去掉。
				if (line.length() == 0)
					spaces.clear();
	
				// 判断当前行加上空格和单词的长度是否超过指定长度,若超过则直接输出当前行
				// 空格清空,单词留到下一行。若未超过则将其合成一行内容。由于两个单词之间可能
				// 是多个空格,所以采用了单独读取空格的方式。
				if ((line.length() + spaces.length() + word.length()) <= WIDTH)
				{
					line.append(spaces).append(word);
					word.clear();
					spaces.clear();
				}
				else
				{
					cout << line << endl;
					line.clear();
					spaces.clear();
				}
			}
		}
	
		// 判断是否有内容仍需要输出。
		if (line.length() > 0)
			cout << line << endl;
		if (word.length() > 0)
			cout << word << endl;
	
		buffer.clear();
	}
}

int main(int ac, char *av[])
{
	string line;
	
	while (getline(cin, line))
	{
		// 截去行末尾的空格。
		trim_line(line);
	
		// 截去行末尾的空格后,空行和只有空格的空白行将都变成空行,有利于判断。
		// 若遇到空行或新行,表示要将前面缓冲区的内容处理输出。
		if (empty_line(line) || new_line(line))
		{
			process_buffer();
			
			// 换行。
			if (empty_line(line))
				cout << endl;
			else
				buffer.append(line);
		}
		else
		{
			// 若缓冲区内容为空,直接将新的一行附加到缓冲区,否则需要在缓冲区和
			// 新一行内容间附加一个空格。
			if (buffer.length() == 0)
				buffer.append(line);
			else
				buffer.append(1, ' ').append(line);
		}
	}
	
	// 处理缓冲区内剩余的内容。
	process_buffer();
	
	return 0;
}


你可能感兴趣的:(c,Date,String,iterator,buffer)