我有一个C ++的小问题,无法通过在线浏览解决。这是我的代码(摘录):
if(File.is_open()) {
while(!File.eof()) {
i++;
getline(File,Line);
if(i>=2) { //Skip Headers
int CharCount=0;
for(int CharPosition=0; CharPosition<Line.size(); CharPosition++) {
if(Line[CharPosition]==',') {
Length=CharPosition;
break;
}
}
NameText=Line.substr(0,Length);
Path= Path_Folder + "\\" + NameText + ".csv";
if(!CheckExistance(Path.c_str())) {
fstream Text_File;
}
Text_File.open(Path, fstream::in | fstream::out | fstream::app);
Text_File<<Line<<"\n";
Text_File.close();
}
}
}
这段代码运行良好,但是我想改变一个事实,即它Text_File
每次在while循环中进入时都会关闭。
基本上,该程序将一个较大的输入文件拆分为许多较小的文件。随着我的小文件越来越大,执行速度越来越慢(正常)。然后,我的目标是让所有较小的文件(Text_File
)在此while循环中打开,并将fstream指针(指针?)从一个切换到另一个。
我试图更改为:
...
NameText=Line.substr(0,Length);
Path= Path_Folder + "\\" + NameText + ".csv";
if(!CheckExistance(Path.c_str())) {
fstream Text_File;
}
if(!Text_File.open()) {
Text_File.open(Path, fstream::in |fstream::out | fstream::app);
}
Text_File<<Line<<"\n";
\\Text_File.close();
...
但是Text_File
不管是什么,它都在相同的条件下工作NameText
。因此,我猜测fstream的指针Text_File
不会改变。那我需要是什么?休息指针?如何?
谢谢你们!
不确定是否相关,但是我正在使用Microsoft Visual C ++ 2010 Express。此外,无论是受过教育还是生活,我都不是程序员,因此,如果您不用太高的词汇就能解释它,我将不胜感激。
看来您想filebuf
在ostream
对象上处理s 。
现在,唯一的障碍是该类型ostream
或该basic_filebuf<char>
类型不是可复制的类型,因此您不能将它们直接放入映射中(按文件名)。通过创建一个小Holder
类型可以很容易地解决这个问题:
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
现在,我得到了以下的输出:看到它住在Coliru
/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
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句