110308 Fmt

来源:互联网 发布:现货交易软件开发 编辑:程序博客网 时间:2024/05/18 01:24

#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 4096static 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;}elsebreak;}// 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 SPACEelseformattedStrCol.push_back(new StrInfo(strInfo.Detach()));}}++iter;break;default: // case NEWLINEif ((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 SPACEbreak;}}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;}


原创粉丝点击