Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <vector>
- enum class Align {
- LEFT, CENTER, RIGHT
- };
- ////////////////////////////////////////////////////////////////////////////////
- struct Word {
- //--------------------------------------------------------------------------
- explicit Word(size_t word_begin, size_t word_end)
- : begin(word_begin),
- end(word_end)
- {}
- //--------------------------------------------------------------------------
- size_t length() const {
- return (begin < end)
- ? end - begin
- : 0;
- }
- //--------------------------------------------------------------------------
- size_t begin;
- size_t end;
- };
- ////////////////////////////////////////////////////////////////////////////////
- std::vector<Word> ScanWords(const std::string & text);
- void Wrap(const std::string& text, size_t width, std::ostream& out);
- std::vector<std::string> Wrap(const std::string& text, size_t width,
- Align align);
- bool WordCouldFitInLine(const std::string & line, const std::string & word,
- size_t width);
- void AppendWordToLine(std::string & line, const std::string word);
- void AlignLineText(std::string & line, size_t width, Align align);
- void TrimLeft(std::string & text);
- void TrimRight(std::string & text);
- void Trim(std::string & text);
- //------------------------------------------------------------------------------
- /**
- * @brief Wraps text lines that exceed limit and writes result to output stream.
- * @param text
- * @param width
- * @param out
- */
- void Wrap(const std::string& text, size_t width, std::ostream& out) {
- auto lines = Wrap(text, width, Align::LEFT);
- for (const auto & line : lines) {
- out << line << std::endl;
- }
- }
- //------------------------------------------------------------------------------
- bool WordCouldFitInLine(const std::string & line, const std::string & word,
- size_t width) {
- const size_t word_length = (line.empty())
- ? word.length()
- : std::string(" ").length() + word.length();
- return line.length() + word_length <= width;
- }
- //------------------------------------------------------------------------------
- void AppendWordToLine(std::string & line, const std::string word) {
- line += (line.empty())
- ? word
- : " " + word;
- }
- //------------------------------------------------------------------------------
- void TrimLeft(std::string & text) {
- size_t first_word_start = text.find_first_not_of(" ");
- text.erase(0, first_word_start);
- }
- //------------------------------------------------------------------------------
- void TrimRight(std::string & text) {
- size_t last_word_end = text.find_last_not_of(" ");
- if (last_word_end < text.length()) {
- text.erase(last_word_end + 1, text.length());
- }
- }
- //------------------------------------------------------------------------------
- void Trim(std::string & text) {
- TrimLeft(text);
- TrimRight(text);
- }
- //------------------------------------------------------------------------------
- void AlignLineText(std::string & line, size_t width, Align align) {
- Trim(line);
- if (!line.empty() && line.length() < width) {
- size_t ws_count = width - line.length();
- switch (align) {
- case Align::LEFT:
- // line += std::string(ws_count, ' ');
- break;
- case Align::CENTER:
- line = std::string(ws_count/2, ' ') + line;
- break;
- case Align::RIGHT:
- line = std::string(ws_count, ' ') + line;
- break;
- }
- }
- }
- //------------------------------------------------------------------------------
- std::vector<std::string> Wrap(const std::string& text, size_t width,
- Align align) {
- std::vector<std::string> result;
- std::string line;
- auto words = ScanWords(text);
- for (const auto & word : words) {
- std::string word_text = text.substr(word.begin, word.length());
- if (WordCouldFitInLine(line, word_text, width)) {
- AppendWordToLine(line, word_text);
- } else {
- AlignLineText(line, width, align);
- result.push_back(line);
- line = "";
- if (WordCouldFitInLine(line, word_text, width)) {
- AppendWordToLine(line, word_text);
- } else {
- // break long word
- std::string long_word_head = text.substr(word.begin, width);
- result.push_back(long_word_head);
- std::string long_word_tail = text.substr(word.begin + width,
- word.length() - width);
- AppendWordToLine(line, long_word_tail);
- }
- }
- }
- if (!line.empty()) {
- AlignLineText(line, width, align);
- result.push_back(line);
- }
- return result;
- }
- //------------------------------------------------------------------------------
- std::vector<Word> ScanWords(const std::string &text) {
- std::vector<Word> words;
- size_t offset = 0;
- const std::string whitespace = " \n";
- while( offset <= text.length() ) {
- const size_t word_start = text.find_first_not_of(whitespace, offset);
- size_t word_end = text.find_first_of(whitespace, word_start);
- if (std::string::npos == word_end) {
- word_end = text.length();
- }
- words.emplace(words.end(), word_start, word_end);
- offset = word_end + 1;
- }
- return words;
- }
- //------------------------------------------------------------------------------
- int main() {
- std::string text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.";
- for (const auto & line : Wrap(text, static_cast<size_t>(40), Align::LEFT)) {
- std::cout << line << std::endl;
- }
- std::cout << std::endl;
- for (const auto & line : Wrap(text, static_cast<size_t>(40), Align::CENTER)) {
- std::cout << line << std::endl;
- }
- std::cout << std::endl;
- for (const auto & line : Wrap(text, static_cast<size_t>(40), Align::RIGHT)) {
- std::cout << line << std::endl;
- }
- std::cout << std::endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement