最近要使用ifstream的getline函数来获取文件的每一行数据,但就搞不懂怎样才能确保获取数据时所使用的缓冲区大小足够大。在刚开始的时候,我是采用了以下的手段:

#include < iostream >
#include < fstream >
using namespace std;
#define BASE_BUFF_MAX_LEN 10
int main()
{
char * filePath = " E:\\test.txt " ;
int bufLen = BASE_BUFF_MAX_LEN;
char * buf = new char [bufLen];
ifstream fin;
fin.open(filePath,ios:: in );
fin.getline(buf,bufLen);
while (fin.fail())
{
fin.getline(buf,bufLen);
}
cout << buf << endl;
}
当缓冲区不够大的时候,getline函数也会对缓冲区输入数据,但同时也会把ifstream的状态位failbit设置了,于是fail函数会返回true。于是上述代码会嵌入死循环,由于处于fail状态下的ifstream,其getline函数不会再读入任何数据,因此后续的getline调用没有效果,并且fail函数一直返回true。
看看文档,原来可以使用ifstream的clear函数重置状态位,于是以下方法就能达到目的:

#include < iostream >
#include < fstream >
using namespace std;
#define BASE_BUFF_MAX_LEN 10
int main()
{
char * filePath = " E:\\test.txt " ;
int bufLen = BASE_BUFF_MAX_LEN;
char * buf = new char [bufLen];
ifstream fin;
fin.open(filePath,ios:: in );
fin.getline(buf,bufLen);
while (fin.fail())
{
fin.clear(ios::goodbit);
fin.getline(buf,bufLen);
}
cout << buf << endl;
}
同时,ifstream的gcount函数会返回上一次读取操作中,读入的有效字符数,但就不保存缓冲区中最后的'\0',因此如果缓冲区大小为10,gcount将输出9。上述方法其实也比较别扭,更好的方法是使用<string>头文件定义的getline:

#include < iostream >
#include < fstream >
#include < string >
using namespace std;
#define BASE_BUFF_MAX_LEN 10
int main()
{
char * filePath = " E:\\test.txt " ;
ifstream fin;
fin.open(filePath,ios:: in );
string s;
getline(fin,s);
cout << s << endl;
}
简单直接。