C++中的文本格式化

3

我正在尝试用C++制作一个基于文本的小游戏,当游戏需要大段文字时,我很难让它看起来美观。我想要统一每行的长度,为了做到这一点,我只能在适当的位置手动输入换行符。是否有命令可以自动实现这个功能?我已经看到了setw()命令,但是如果文本超过宽度,它并不能自动换行。有什么建议吗?以下是我目前正在做的事情,如果有帮助的话。

cout << "    This is essentially what I do with large blocks of" << '\n';
cout << "    descriptive text. It lets me see how long each of " << '\n';
cout << "    the lines will be, but it's really a hassle, see? " << '\n';            

1
使用头文件<iomanip>,它提供了各种文本格式化函数。 - user4418808
@RohitSaluja,你能具体一点吗?我在找到的列表中只看到了setw(),但我不认为它有效。或者你可以发一个例子来说明如何做到这一点吗? - Hammurabi8
3个回答

2

编写一个库函数,自动插入适合特定输出宽度的前导空格和换行符是个好主意。本网站认为库推荐不属于讨论范围,但我在下面提供了一些代码 - 不是特别高效,但易于理解。基本逻辑应该是向前跳转到字符串中的最大宽度,然后向后移动,直到找到你准备断开行的空格(或可能是连字符)...然后打印前导空格和剩余部分的行。继续直到完成。

#include <iostream>

std::string fmt(size_t margin, size_t width, std::string text)
{
    std::string result;
    while (!text.empty())   // while more text to move into result
    {
        result += std::string(margin, ' ');  // add margin for this line

        if (width >= text.size())  // rest of text can fit... nice and easy
            return (result += text) += '\n';

        size_t n = width - 1;  // start by assuming we can fit n characters
        while (n > width / 2 && isalnum(text[n]) && isalnum(text[n - 1]))
            --n; // between characters; reduce n until word breaks or 1/2 width left

        // move n characters from text to result...
        (result += text.substr(0, n)) += '\n';
        text.erase(0, n);
    }
    return result;
}

int main()
{
    std::cout << fmt(5, 70,
        "This is essentially what I do with large blocks of "
        "descriptive text. It lets me see how long each of "
        "the lines will be, but it's really a hassle, see?"); 

}

这部分代码尚未经过充分测试,但似乎能够工作。您可以在此处查看运行情况。如果需要其他替代方案,请参考这个SO问题

顺便说一句,您的原始代码可以简化为...

cout << "    This is essentially what I do with large blocks of\n"
        "    descriptive text. It lets me see how long each of\n"
        "    the lines will be, but it's really a hassle, see?\n"; 

...由于C++在遇到分号之前会认为语句未完成,因此在代码中相邻出现的双引号字符串字面量会自动连接在一起,就像内部的双引号和空格被删除一样。


我对编程非常不熟悉,我认为这有点超出了我的技能水平。我非常惊讶这种东西居然不存在。 - Hammurabi8
太棒了,这个完美地运行了!我会花一些时间来研究它,弄清楚它的所有工作原理,但我真的很印象深刻。谢谢你如此迅速并且专业地回复! - Hammurabi8
@Hammurabi8:没问题,我添加了更多的注释/解释 - 希望这也有所帮助。干杯。 - Tony Delroy

1
你可以编写一个简单的三元函数。
void print(const std::string& brute, int sizeline)
{
     for(int i = 0; i < brute.length(); i += sizeline)
          std::cout << brute.substr(i, sizeline) << std::endl;
}

int main()
{
     std::string mytext = "This is essentially what I do with large blocks of"
                          "descriptive text. It lets me see how long each of "
                          "1the lines will be, but it's really a hassle, see?";

     print(mytext, 20);

     return 0;
}

但是单词会被切断。
输出:
This is essentially 
what I do with large
 blocks ofdescriptiv
e text. It lets me s
ee how long each of 
1the lines will be, 
but it's really a ha
ssle, see?

这很简单而且有用,谢谢。不过,我该怎么做才能防止它把单词分开呢? - Hammurabi8

1

有一个非常好用的文本格式处理库,名为cppformat/cppformat,可在github上找到。

使用它,您可以轻松地操纵文本格式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接