【问题标题】:How to print "justified" text in the console using modern C++如何使用现代 C++ 在控制台中打印“对齐”文本
【发布时间】:2014-04-10 08:44:46
【问题描述】:

如何格式化文本“对齐”,使其在给定宽度下左右对齐?

int main()
{
    printJustified("A long text with many words. "
        "A long text with many words. "
        "A long text with many words. "
        "A long text with many words. "
        "A long text with many words.");
}

预期输出:

A  long text with many words. A long text with
many  words.  A  long  text with many words. A
long text with many words.

【问题讨论】:

  • @JoachimPileborg 他似乎也想要辩解。 (不是固定宽度的字体是个好主意,否则也不是微不足道的。)

标签: c++ stream formatting string-formatting


【解决方案1】:

如何解决这个问题的一个简单例子是这样的:

#include <iostream>
#include <sstream>
#include <list>

const int pageWidth = 78;
typedef std::list<std::string> WordList;

WordList splitTextIntoWords( const std::string &text )
{
    WordList words;
    std::istringstream in(text);
    std::copy(std::istream_iterator<std::string>(in),
              std::istream_iterator<std::string>(),
              std::back_inserter(words));
    return words;
}

void justifyLine( std::string line )
{
    size_t pos = line.find_first_of(' ');
    if (pos != std::string::npos) {
        while (line.size() < pageWidth) {
            pos = line.find_first_not_of(' ', pos);
            line.insert(pos, " ");
            pos = line.find_first_of(' ', pos+1);
            if (pos == std::string::npos) {
                pos = line.find_first_of(' ');
            }
        }
    }
    std::cout << line << std::endl;
}

void justifyText( const std::string &text )
{
    WordList words = splitTextIntoWords(text);

    std::string line;
    for (const std::string& word : words) {
        if (line.size() + word.size() + 1 > pageWidth) { // next word doesn't fit into the line.
            justifyLine(line);
            line.clear();
            line = word;
        } else {
            if (!line.empty()) {
                line.append(" ");
            }
            line.append(word);
        }
    }
    std::cout << line << std::endl;
}

int main()
{
    justifyText("This small code sample will format a paragraph which "
        "is passed to the justify text function to fill the "
        "selected page with and insert breaks where necessary. "
        "It is working like the justify formatting in text "
        "processors.");
    return 0;
}

它是这样工作的:

  • 首先将文本拆分为单词。
  • 单词被添加到行中,直到该行不能容纳更多单词。
  • 对于每一行,在单词之间添加空格,直到该行与请求的宽度匹配。

【讨论】:

  • 两件事:首先不要循环while (in),它不会像你期望的那样工作。而是做while (in &gt;&gt; word)。其次,我建议您阅读std::copystd::istream_iteratorstd::back_inserter,而不是循环。
  • 另外,如果你的编译器足够现代,可以支持它,你可能想了解一下range-base for loops
  • @JoachimPileborg 你能用你建议的更改进行编辑吗?
  • 好的,完成。最大的区别是将文本拆分为单词的函数,现在不是循环,而是单个函数调用。基于范围的 for 循环的变化不是迭代器。请注意,对于新的循环构造,您需要一个支持 C++11 的编译器。我留下了旧代码的注释。
  • @JoachimPileborg 太好了,谢谢!它确实简化了代码。我删除了注释掉的代码以避免混淆。
猜你喜欢
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-28
  • 2020-12-09
  • 2020-09-05
  • 1970-01-01
相关资源
最近更新 更多