Wil*_*mKF 17 c++ stream ofstream
是否有一种简单的方法可以将输出缩进到ofstream对象?我有一个C++字符数组,它是null终止并包含换行符.我想将它输出到流中,但是用两个空格缩进每一行.有没有一种简单的方法可以使用流操纵器来执行此操作,例如您可以使用特殊指令更改整数输出的基础,或者我是否必须手动处理数组并在检测到的每个换行符时手动插入额外的空格?
看起来像string :: right()操纵器是关闭的:
http://www.cplusplus.com/reference/iostream/manipulators/right/
谢谢.
-威廉
Mar*_*ork 21
这是使用方面的完美情况.
codecvt facet的自定义版本可以嵌入到流中.
所以你的用法看起来像这样:
int main()
{
/* Imbue std::cout before it is used */
std::ios::sync_with_stdio(false);
std::cout.imbue(std::locale(std::locale::classic(), new IndentFacet()));
std::cout << "Line 1\nLine 2\nLine 3\n";
/* You must imbue a file stream before it is opened. */
std::ofstream data;
data.imbue(indentLocale);
data.open("PLOP");
data << "Loki\nUses Locale\nTo do something silly\n";
}
Run Code Online (Sandbox Code Playgroud)
方面的定义稍微复杂一些.
但重点是使用facet的人不需要知道格式化的任何信息.应用格式不依赖于流的使用方式.
#include <locale>
#include <algorithm>
#include <iostream>
#include <fstream>
class IndentFacet: public std::codecvt<char,char,std::mbstate_t>
{
public:
explicit IndentFacet(size_t ref = 0): std::codecvt<char,char,std::mbstate_t>(ref) {}
typedef std::codecvt_base::result result;
typedef std::codecvt<char,char,std::mbstate_t> parent;
typedef parent::intern_type intern_type;
typedef parent::extern_type extern_type;
typedef parent::state_type state_type;
int& state(state_type& s) const {return *reinterpret_cast<int*>(&s);}
protected:
virtual result do_out(state_type& tabNeeded,
const intern_type* rStart, const intern_type* rEnd, const intern_type*& rNewStart,
extern_type* wStart, extern_type* wEnd, extern_type*& wNewStart) const
{
result res = std::codecvt_base::noconv;
for(;(rStart < rEnd) && (wStart < wEnd);++rStart,++wStart)
{
// 0 indicates that the last character seen was a newline.
// thus we will print a tab before it. Ignore it the next
// character is also a newline
if ((state(tabNeeded) == 0) && (*rStart != '\n'))
{
res = std::codecvt_base::ok;
state(tabNeeded) = 1;
*wStart = '\t';
++wStart;
if (wStart == wEnd)
{
res = std::codecvt_base::partial;
break;
}
}
// Copy the next character.
*wStart = *rStart;
// If the character copied was a '\n' mark that state
if (*rStart == '\n')
{
state(tabNeeded) = 0;
}
}
if (rStart != rEnd)
{
res = std::codecvt_base::partial;
}
rNewStart = rStart;
wNewStart = wStart;
return res;
}
// Override so the do_out() virtual function is called.
virtual bool do_always_noconv() const throw()
{
return false; // Sometime we add extra tabs
}
};
Run Code Online (Sandbox Code Playgroud)
请参阅:Tom的笔记如下