打印文件时如何格式化文件的内容,使文件的内容居中?

时间:2019-08-14 09:47:01

标签: c++ boost file-io

假设我有一个文件abc.txt。该文件包含大量文本段落(例如,这一段:https://loremipsum.io/generator/?n=5&t=p)。

我正在尝试使用abc.txtstringstreamrdbuf()的内容读取并打印到控制台上。虽然控制台上显示的文本是完美的,但我想在每行的开头加上n空格,并在结尾处也使用相同的n空格。

例如,一行:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor

应成为:

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor    

在这里,我用4个空格填充了行的开头和结尾。

请注意,我不想以任何方式更改文件。它本身以read模式打开,不允许对其进行任何写操作。

我在SO上遇到了很多有关“在C ++中居中放置文本”的答案,但是大多数答案都使用setw。对于我来说,不可能知道每行可能包含不同的宽度(一行中的字符数),并且setw必须大于输出(行)的宽度。

我该怎么做?

这是我现在从文件读取并将其发送到控制台的方式:

string file_slurper(std::ifstream& infile)
{
    stringstream ssm;
    ssm << infile.rdbuf();
    return ssm.str();
}

std::ifstream read_f(files[ch_index]);
if (read_f.is_open())
{
    cout << file_slurper(read_f);
}

此外,如果有帮助,我在此文件中使用Boost库,因此如果更好,您也可以从Boost中提出一些建议。

2 个答案:

答案 0 :(得分:1)

(我假设您的意思是相对于终端居中)

与其直接打印,不如将其作为字符串获取,将其长度与终端宽度进行比较(请参见Get size of terminal window (rows/columns))并相应地进行填充。

请注意,当字符串大于终端时,您必须考虑该怎么做。

void print_centered(const string& str)
{
    int difference = terminal_width() - str.length() ;
    if(difference < 0)
    {
        // see edit note below
        cout << str.substr(0, terminal_width()) << endl;
        print_centered(str.substr(terminal_width(), str.length() - terminal_width());
    }
    else
    {
        cout << string(difference/2, ' ');
        cout << str << endl;
    }
}

(如以上链接中所述,int terminal_width()已实现,如果您使用多个平台,则可能有多个版本)

编辑:为差异<0的情况创建了一些内容,将其打印出可以显示的内容,然后将尾巴居中。
对于8的终端宽度,单词abcdefghijklmnopqrstuvwxyz将被打印为(用_表示空格)

abcdefgh
ijklmnop
qrstuvwx
___yz___

更复杂的方法可能是用连字符将新行分隔开,如果可能的话,可能尝试通过保持单词完整来进行分隔,甚至可能像人一样聪明地将单词分隔开(就像文本软件通常那样) ,尽管这需要一些大的努力(或者是一个非常好的了解语言的库)。

请注意,在任何情况下,如果在打印后用户调整了终端窗口的大小,那么居中当然将不再是

另外,从您问题的评论中,您似乎出于速度原因不赞成getline
如果要这样做,您几乎必须逐行阅读,而且正如有人已经说过的那样,阅读和打印都已经很慢了,我真的很想知道您是否能够注意到任何区别。
在这里也许是一个重要的建议,过早的优化通常是一个错误。仅在出现问题时才进行速度优化。

答案 1 :(得分:0)

如果要使输出居中,则需要在每行前面添加可变数量的空格,该数量为((端子的宽度)-(要打印的行的长度)/ 2)。为了能够分辨每行的长度,您需要逐行读取输入内容,而不是逐字符读取。 std::getline是一个很好的功能。

如果要在每行前面填充n个空格,请在每行前面打印n个空格。您还可以在每行之后打印n个空格,但这可能对可见输出没有影响,除了可能的丑陋和不必要的换行。至少使用不可见空格的默认设置。在这种情况下,也方便使用std::getline。另外,您可以逐字符输出字符,并自己查看换行符。