通过使用指向igzstreams的指针的STL向量来读取gzip文件
Read gzipped files by using a STL vector of pointers to igzstreams
作为输入,我有一个gzip文件列表。如这里所示,我使用gzstream来处理它们。出于实际原因,我想打开每个文件并将每个流记录为矢量。这似乎很简单,但我没有设法使它工作。下面是最简单的代码:
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
#include <gzstream.h>
int main (int argc, char ** argv)
{
size_t i;
vector<string> vInFiles;
vector<igzstream *> vStreams;
string line;
// create the dummy input files
system ("rm -f infile*.gz; for i in {1..2}; do echo "toto"${i} | gzip > infile${i}.gz; done");
vInFiles.push_back ("infile1.gz");
vInFiles.push_back ("infile2.gz");
// open each input file
for (i = 0; i < vInFiles.size(); ++i)
{
igzstream inStream;
inStream.open (vInFiles[i].c_str());
if (! inStream.good())
{
cerr << "ERROR: can't open file " << vInFiles[i] << endl;
exit (1);
}
vStreams.push_back (&inStream);
}
// manipulate each input file
for (i = 0; i < vInFiles.size(); ++i)
{
cout << "read first line of file " << vInFiles[i] << endl;
getline (*(vStreams[i]), line);
if (line.empty())
{
cerr << "empty line" << endl;
exit (1);
}
cout << line << endl;
}
// close each input file
for (i = 0; i < vInFiles.size(); ++i)
{
vStreams[i]->close();
}
vStreams.clear();
return 0;
}
下面的代码可以正常编译:
$ gcc -Wall test.cpp -lstdc++ -lgzstream -lz
虽然它运行得很顺利,但它不能正确读取文件:
$ ./a.out
read first line of file infile1.gz
empty line
你的流指针在迭代结束后无效,因为自动流对象在迭代结束后被销毁。如果你真的需要,你需要在自由存储中分配它们(或者使igzstream
可移动)。
// std::vector<boost::shared_ptr<igzstream>> for C++03
std::vector<std::unique_ptr<igzstream>> vStreams;
// ...
for (size_t i = 0; i < vInFiles.size(); ++i) {
// boost::shared_ptr<igzstream> inStream = boost::make_shared<igzstream>();
auto inStream = std::unique_ptr<igzstream>(new igzstream);
inStream->open(...);
// ...
vStreams.push_back(inStream);
}
// ...
存储指向流的指针向量,但使用指向流的局部作用域自动实例的指针初始化它(在for循环中)。一旦循环的每次迭代完成,该实例就超出了作用域,并且您有一个指向某些垃圾的指针。
你以后再用这些垃圾,你就会得到垃圾。
使用智能指针,例如
std::vector<boost::shared_ptr<igzstream> > vStreams;
// to initialize
for (i = 0; i < vInFiles.size(); ++i)
{
boost::shared_ptr<igzstream> inStream(new igzstream(vInFiles[i].c_str());
if (!inStream->good())
{
cerr << "ERROR: can't open file " << vInFiles[i] << endl;
exit (1);
}
vStreams.push_back (inStream); // save the smart pointer
}
正如评论中提到的,我不喜欢使用Boost,我只有gcc 4.1.2。因此,下面是使用免费商店的解决方案,感谢Cat Plus Plus的建议:
// open each input file
for (i = 0; i < vInFiles.size(); ++i)
{
igzstream * pt_inStream = new igzstream;
pt_inStream->open (vInFiles[i].c_str());
if (! pt_inStream->good())
{
cerr << "ERROR: can't open file " << vInFiles[i] << endl;
exit (1);
}
vStreams.push_back (pt_inStream);
}
:
// close each input file
for (i = 0; i < vInFiles.size(); ++i)
{
vStreams[i]->close();
delete vStreams[i];
}
相关文章:
- 对象 C++ 向量的 STL 容器
- 具有 STL 向量类型成员的类的复制内存
- 如何使用 STL 算法将整数向量转换为字符串向量?
- 为什么C++ STL 哈希表 (unordered_map) 不接受向量作为键
- STL 向量无缘无故损坏,VC++ 2017
- 如何避免自定义 STL 向量类的智能指针 delete[] 异常?
- STL向量上出现奇怪的复制构造函数错误
- OpenMP 和不同的 STL 向量
- STL按客户"<"运算符对向量进行排序。为什么要将"<"运算符定义为 const?
- C++ STL 向量保留太多容量会消耗大量内存吗?
- 如何通过 stl 容器和算法库计算两个向量的内积?
- 使用 boost Spirit 解析为 STL 向量
- C++ 在列表末尾插入元素的列表的 STL 向量
- C++ 使用数组初始化时的 STL 向量内存管理
- 使用STL算法合并2个向量
- 仅编写 c++ stl 向量的第一个元素的正确方法
- 如何在<typename> <long> 不更改给定代码的情况下将自定义向量与 STL 向量相互转换?
- 限制指针访问STL ::向量元素
- 使用向量(STL)时,未定义的行为,请说明理性背后的以下代码输出
- C++:问题向量 STL.