#include <stdio.h>
#include <iostream>
#include <string>
#include <string.h>
#include <vector>
using namespace std;
enum CharType_t
{
SPACE,
NEWLINE,
NORMAL
};
struct StrInfo
{
StrInfo(char* str, int len, CharType_t charType) :
m_len(len), m_charType(charType)
{
m_str = new string(str);
}
StrInfo(string* str) : m_str(str)
{
}
~StrInfo()
{
if (m_str)
delete m_str;
}
string* Detach()
{
string* tmp = m_str;
m_str = NULL;
return tmp;
}
void Change(char* str, int len, CharType_t charType)
{
if (m_str)
delete m_str;
m_str = new string(str);
m_len = len;
m_charType = charType;
}
string* m_str;
int m_len;
CharType_t m_charType;
};
typedef vector<StrInfo*> StringCol;
#define MAX_CHARS 72
#define MAX_BUF 4096
static void ClearStringCol(StringCol& strCol)
{
StringCol::iterator iter = strCol.begin();
while(iter != strCol.end())
{
delete (*iter);
++iter;
}
}
static void AddStrsFromLineToStringCol(StringCol& strCol, char* line)
{
if (!line)
return;
int len = strlen(line);
int i = 0, j;
char originalEnd;
while(i < len)
{
switch(line[i])
{
case ' ':
strCol.push_back(new StrInfo(" ", 1, SPACE));
++i;
break;
case '\n':
strCol.push_back(new StrInfo("\n", 1, NEWLINE));
++i;
break;
default:
j = i + 1;
while((line[j] != ' ') && (line[j] != '\n') && (line[j] != '\0'))
++j;
originalEnd = line[j];
line[j] = '\0';
strCol.push_back(new StrInfo(line + i, j - i, NORMAL));
line[j] = originalEnd;
i = j;
break;
}
}
}
static void StartNewLine(int& curCharsCntInLine, bool& curLineIsBlank, StringCol& strCol)
{
// Delete the spaces in the end of the line first.
int last = strCol.size() - 1;
while(last >= 0)
{
if ((*(strCol[last]->m_str))[0] == ' ')
{
delete strCol[last];
strCol.pop_back();
--last;
}
else
break;
}
// Now we can add the new line and reset the count and flag.
strCol.push_back(new StrInfo(new string("\n")));
curCharsCntInLine = 0;
curLineIsBlank = true;
}
static void AddStrToFormattedStrCol(
StringCol::iterator& iter, const StringCol::iterator& end, StringCol& formattedStrCol,
int& curCharsCntInLine, bool& curLineIsBlank)
{
StrInfo& strInfo = *(*iter);
switch(strInfo.m_charType)
{
case NORMAL:
curCharsCntInLine += strInfo.m_len;
curLineIsBlank = false;
formattedStrCol.push_back(new StrInfo(strInfo.Detach()));
++iter;
break;
case SPACE:
curCharsCntInLine += strInfo.m_len;
if (curCharsCntInLine >= MAX_CHARS)
{
StartNewLine(curCharsCntInLine, curLineIsBlank, formattedStrCol);
}
else
{
if ((iter + 1) != end)
{
StrInfo& nextStrInfo = *(*(iter + 1));
if ((curCharsCntInLine + nextStrInfo.m_len) > MAX_CHARS)
StartNewLine(curCharsCntInLine, curLineIsBlank, formattedStrCol); // Ignore this SPACE
else
formattedStrCol.push_back(new StrInfo(strInfo.Detach()));
}
}
++iter;
break;
default: // case NEWLINE
if ((iter + 1) == end)
{
StartNewLine(curCharsCntInLine, curLineIsBlank, formattedStrCol);
++iter;
}
else if (curLineIsBlank ||
((*(iter+1))->m_charType == NEWLINE) ||
((*(iter+1))->m_charType == SPACE))
{
StartNewLine(curCharsCntInLine, curLineIsBlank, formattedStrCol);
++iter;
}
else
(*iter)->Change(" ", 1, SPACE); // Ignore this NEWLINE and change it to SPACE
break;
}
}
static void FormatStrCol(StringCol& originalStrCol, StringCol& formattedStrCol)
{
StringCol::iterator iter = originalStrCol.begin();
int curCharsCntInLine = 0;
bool curLineIsBlank = true;
while(iter != originalStrCol.end())
AddStrToFormattedStrCol(iter, originalStrCol.end(), formattedStrCol, curCharsCntInLine, curLineIsBlank);
}
static void OutputStrCol(const StringCol& strCol)
{
StringCol::const_iterator iter = strCol.begin();
while(iter != strCol.end())
{
cout << (*((*iter)->m_str));
++iter;
}
}
static void GetInputs(StringCol& strCol)
{
char buf[MAX_BUF];
while(fgets(buf, MAX_BUF, stdin))
{
if (buf[0] == '\0')
return;
AddStrsFromLineToStringCol(strCol, buf);
}
}
static void DoTest()
{
StringCol originalStrCol, formattedStrCol;
GetInputs(originalStrCol);
FormatStrCol(originalStrCol, formattedStrCol);
OutputStrCol(formattedStrCol);
ClearStringCol(originalStrCol);
ClearStringCol(formattedStrCol);
}
int main(int argc, char* argv[])
{
DoTest();
return 0;
}
110308 Fmt
最新推荐文章于 2013-12-18 15:39:30 发布