在 ifstream 上的 getlines [耗尽文件] 之后 seekg 的问题
problems with seekg after getlines[which exhausts file] on ifstream
我正在尝试编写一个程序来打印文件的最后一行,我想出了以下方法。我在文件中做 SEEKs
的地方,但这段代码在无限循环中运行。如果我注释掉 (1)
并启用 (2)
,代码工作正常。我无法找出原因。
#include <iostream>
#include <fstream>
int main()
{
std::string line;
int count = 0;
long int seek_length = -1l;// should be -100l
std::ifstream ifile("D:\cprog\test.csv");// --(1)
while(true){
seek_length *= 2;
count = 0;
//std::ifstream ifile("D:\cprog\test.csv"); //-- (2)
ifile.seekg(seek_length, std::ios_base::end);
while(std::getline(ifile,line)){
++count;
}
if(count > 1)
break;
}
std::cout << line << '\n';
}
编译器:g++ (GCC) 4.9.2 (MINGW)
您需要在再次阅读之前清除流中的错误状态:
ifile.clear();
否则,第一次遇到 EOF 时,流会进入错误状态,所有后续读取都将失败。
请注意,如果您执行此操作并且您的文件仅包含 1(或 0)行,则当前形式的代码将永远循环。
最终工作代码如下,问题可以通过以下方式之一解决。
#include <iostream>
#include <fstream>
int main()
{
std::string line;
int count = 0;
long int seek_length = -100l;
std::ifstream ifile("D:\cprog\test.csv");
#if 0
while(true){
seek_length *= 2;
count = 0;
ifile.seekg(seek_length, std::ios_base::end);
if( ifile.tellg() < 0 ){
ifile.clear();
ifile.seekg(0l, std::ios_base::beg);
while(std::getline(ifile,line));
break;
}
else
{
while(std::getline(ifile,line)){
++count;
}
if(count > 1)
break;
}
ifile.clear();
}
#else
char ch;
ifile.seekg(0l, std::ios_base::end);
do
{
ch = ifile.peek();
ifile.seekg(-1l, std::ios_base::cur);
std::cout << ch <<'~' << ifile.tellg() <<'\n';
}while(ch != '\n' && ifile.tellg() > -1 );
if(ifile.tellg() < 0 )
ifile.seekg(0l, std::ios_base::beg);
else
ifile.seekg(2l, std::ios_base::cur);
ifile.clear();
std::getline(ifile,line);
#endif
if(line.empty())
std::cout<<"------- EMPTY LINE -----\n";
else std::cout << line << '\n';
}
我正在尝试编写一个程序来打印文件的最后一行,我想出了以下方法。我在文件中做 SEEKs
的地方,但这段代码在无限循环中运行。如果我注释掉 (1)
并启用 (2)
,代码工作正常。我无法找出原因。
#include <iostream>
#include <fstream>
int main()
{
std::string line;
int count = 0;
long int seek_length = -1l;// should be -100l
std::ifstream ifile("D:\cprog\test.csv");// --(1)
while(true){
seek_length *= 2;
count = 0;
//std::ifstream ifile("D:\cprog\test.csv"); //-- (2)
ifile.seekg(seek_length, std::ios_base::end);
while(std::getline(ifile,line)){
++count;
}
if(count > 1)
break;
}
std::cout << line << '\n';
}
编译器:g++ (GCC) 4.9.2 (MINGW)
您需要在再次阅读之前清除流中的错误状态:
ifile.clear();
否则,第一次遇到 EOF 时,流会进入错误状态,所有后续读取都将失败。
请注意,如果您执行此操作并且您的文件仅包含 1(或 0)行,则当前形式的代码将永远循环。
最终工作代码如下,问题可以通过以下方式之一解决。
#include <iostream>
#include <fstream>
int main()
{
std::string line;
int count = 0;
long int seek_length = -100l;
std::ifstream ifile("D:\cprog\test.csv");
#if 0
while(true){
seek_length *= 2;
count = 0;
ifile.seekg(seek_length, std::ios_base::end);
if( ifile.tellg() < 0 ){
ifile.clear();
ifile.seekg(0l, std::ios_base::beg);
while(std::getline(ifile,line));
break;
}
else
{
while(std::getline(ifile,line)){
++count;
}
if(count > 1)
break;
}
ifile.clear();
}
#else
char ch;
ifile.seekg(0l, std::ios_base::end);
do
{
ch = ifile.peek();
ifile.seekg(-1l, std::ios_base::cur);
std::cout << ch <<'~' << ifile.tellg() <<'\n';
}while(ch != '\n' && ifile.tellg() > -1 );
if(ifile.tellg() < 0 )
ifile.seekg(0l, std::ios_base::beg);
else
ifile.seekg(2l, std::ios_base::cur);
ifile.clear();
std::getline(ifile,line);
#endif
if(line.empty())
std::cout<<"------- EMPTY LINE -----\n";
else std::cout << line << '\n';
}