看起来你想兼顾filebuf
s on an ostream
object.
现在,唯一的障碍是ostream
or basic_filebuf<char>
不是可复制的类型,因此您不能直接将它们放入映射(按文件名)中。通过创建一些内容可以轻松解决这个问题Holder
type:
struct Holder {
Holder(std::string const& path)
: buf(std::make_shared<std::filebuf>())
{
buf->open(path.c_str(), std::ios::out | std::ios::app);
}
std::shared_ptr<std::filebuf> buf;
};
std::map<std::string, Holder> buffers;
现在完整的程序(经过测试)将如下所示:
#include <fstream>
#include <sstream>
#include <iostream>
#include <map>
#include <memory>
const std::string Path_Folder = ".";
int main()
{
std::istream& File = std::cin; // just for example
std::filebuf dummy;
std::ostream TextFile(&dummy);
struct Holder {
Holder(std::string const& path)
: buf(std::make_shared<std::filebuf>())
{
buf->open(path.c_str(), std::ios::out | std::ios::app);
}
std::shared_ptr<std::filebuf> buf;
};
std::map<std::string, Holder> buffers;
int i = 0;
std::string Line;
while(getline(File, Line))
{
if (i++<2)
continue; //Skip Headers
auto NameText = Line.substr(0, Line.find(','));
auto Path = Path_Folder + '/' + NameText + ".csv";
// open, only if not allready opened
auto found = buffers.find(NameText);
if (end(buffers) == found)
found = buffers.insert({ NameText, Path }).first;
TextFile.rdbuf(found->second.buf.get());
TextFile << Line << std::endl; // notice implicit std::flush in std::endl
}
// all files are automatically closed here
}
另外三点注意:
- 当文件被自动关闭时
buffers
地图超出范围。
- 您可能需要在切换时添加显式刷新
rdbuf()
像这样,如果你不以隐式结束你的行std::flush
(就像std::endl
).
-
dummy
存在只是为了拥有一个ostream
我们可以切换缓冲区的对象
我使用以下输入对此进行了测试:
Header Row #1
Header Row #2
Jack,1,some data
Jill,2,some more data
Jack,3,not reopening :)
Jill,4,jill still receiving output
Romeo,5,someone else reporting
现在,我得到以下输出:see it 住在科利鲁 http://coliru.stacked-crooked.com/view?id=9c388874ad76178c7bcdd49beeae01a9-9c316e88ae784971c383263e9035353b
/tmp$
rm *.csv
/tmp$
make && ./test < input.txt && tail *.csv
g++ -std=c++11 -Wall -g test.cpp -o test
==> Jack.csv <==
Jack,1,some data
Jack,3,not reopening :)
==> Jill.csv <==
Jill,2,some more data
Jill,4,jill still receiving output
==> Romeo.csv <==
Romeo,5,someone else reporting