假设我有一个文件 abc.txt
。该文件包含大量文本段落(例如,这个:https://loremipsum.io/generator/?n=5&t=p)。
我尝试使用 stringstream
和 rdbuf()
读取 abc.txt
的内容并将其打印到控制台上。虽然控制台上显示的文本是完美的,但我想用 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 中推荐一些更好的东西。
最佳答案
(我假设你的意思是相对于终端居中)
不是直接打印它,而是将它作为一个字符串获取,将它的长度与终端宽度进行比较(参见 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()
实现,如上面链接中所述,如果您使用多个平台,可能有多个版本)
编辑:为 difference < 0 case 创建了一些东西,打印它可以打印的内容,然后将尾部居中。
对于 8 的终端宽度,单词 abcdefghijklmnopqrstuvwxyz 将打印为(空格为 _)
abcdefgh
ijklmnop
qrstuvwx
___yz___
一种更复杂的方法可能会用连字符分隔新行,可能会尝试通过尽可能保持单词完整来分隔,或者甚至可能足够聪明,可以像人一样在单词内进行分隔(就像文本软件通常所做的那样) ,尽管这需要付出很大的努力(或者一个非常好的了解语言的库)。
请注意,在任何情况下,如果用户在打印后调整终端窗口的大小,居中当然会停止。
另外,从你的问题的评论来看,你似乎不喜欢 getline
因为速度的原因:
如果你想这样做,你几乎必须逐行阅读,正如有人已经说过的,阅读和打印都已经很慢了,我真的很想知道你是否能够注意到任何差异。
也许这里有一个重要的建议,过早的优化通常是一个错误。只有在速度成为问题时才优化速度。
关于c++ - 打印时如何格式化文件内容,使文件内容居中显示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57492242/