gpt4 book ai didi

c++ - 如何在不关闭 fstream 文件的情况下切换它们(同时输出文件)-C++

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:20:37 24 4
gpt4 key购买 nike

我有一个 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();
}
}
}

这段代码工作正常,但我想改变它每次进入 while 循环时关闭 Text_File 的事实。

基本上,这个程序将一个大的输入文件分成许多小文件。作为我的小文件变得越来越大,执行越来越慢(普通的)。我的目标是让所有较小的文件 (Text_File) 在这个 while 循环,只是将 fstream 指针(指针?)从 1 切换到另一个。

我试着改成:

...

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();

...

但无论 NameText 是什么,它都在同一个 Text_File 上工作。所以我猜测 fstream Text_File 的指针没有改变。那我需要做什么?休息指针?怎么办?

谢谢大家!

不确定是否相关,但我正在使用 Microsoft Visual C++ 2010 Express。另外,我既不是教育也不是生活的程序员,所以如果你能用不太高级的话解释一下,我将不胜感激。

最佳答案

看起来您想兼顾 filebufostream 上对象。

现在,唯一的障碍是 ostreambasic_filebuf<char>不是可复制的类型,因此您不能将它们直接放入 map (按文件名)。这很容易通过创建一个小的 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 时自动关闭 map 超出范围。
  • 您可能需要在切换时添加显式刷新 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 live at 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

关于c++ - 如何在不关闭 fstream 文件的情况下切换它们(同时输出文件)-C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17888569/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com