我正在尝试探索ifstream类并编写下面的代码来读取文件Test.txt
'Test.txt' - 内容
This is Line One
This is Line Two
This is Line Three
This is Line Four
This is Line Five
代码编写:
#include <iostream>
#include <fstream>
#include <limits>
using namespace std;
int main()
{
char buff[50];
char ch;
ifstream is("test.txt");
if (!is)
cout << "Unable to open " << endl;
while(is)
{
ch=(char)is.get();
if(ch != EOF)//If EOF is not checked then
//EOF converted as a char is displyed as
// last char of the file
cout << ch;
}
cout << "\n\n###########\n\n";
is.clear(); //clearing ios_base::eofbit which was set
//in previous action
is.seekg(0,ios_base::beg); //Going back to start of File
while(is)
{
is.get(buff,50,'\n');
cout << buff ;
cout << "\n--------------\n";
is.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
//Flushing the is stream as '\n' was left by get fn
}
cout << "\n\n@@@@@@@@@@@@@@\n\n";
is.clear();
is.seekg(0,ios_base::beg);
while(!is.eof())
{
is.getline(buff,50,'\n');
cout << buff;
cout << "\n--------------\n";
//No need to flush the is stream as '\n'
//was extracted and discarded by getline
}
cout << "\n\n$$$$$$$$$$$$$$\n\n";
is.clear();
is.seekg(0,ios_base::end);
int size=is.tellg();
is.seekg(0,ios_base::beg);
cout << "size : " << size << endl;
//char* readBuff = (char *) ::operator new(sizeof(char)*size);
char* readBuff = new char[size];
is.read(readBuff,size);
cout << readBuff;
delete(readBuff);
is.close();
return 0;
}
输出:
Gaurav@Gaurav-PC /cygdrive/d/Trial
$ ./Trial
This is Line One
This is Line Two
This is Line Three
This is Line Four
This is Line Five
###########
This is Line One
--------------
This is Line Two
--------------
This is Line Three
--------------
This is Line Four
--------------
This is Line Five
--------------
@@@@@@@@@@@@@@
This is Line One
--------------
This is Line Two
--------------
This is Line Three
--------------
This is Line Four
--------------
This is Line Five
--------------
$$$$$$$$$$$$$$
size : 92
This is Line One
This is Line Two
This is Line Three
This is Line Four
This is Line Five▒u
我想问一些问题并澄清:
1)当我使用get
如下
while(is)
{
is.get(buff,50,'\n');
cout << buff ;
// cout << "\n--------------\n";
is.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
//Flushing the is stream as '\n' was left by get fn
}
即。我注释掉了cout << "\n--------------\n";
,然后将文件读作
###########
This is Line Fivee
即。它错过了前四行,只读了最后一行'e'
..但是不知道为什么会这样?
2)当我使用getline
时,如下所示:
// while(!is.eof())
while(is)
{
is.getline(buff,50,'\n');
cout << buff;
cout << "\n--------------\n";
//No need to flush the is stream as '\n'
//was extracted and discarded by getline
}
即。我使用了while(is)
而不是while(!is.eof())
- 我得到了输出:
@@@@@@@@@@@@@@
This is Line One
--------------
This is Line Two
--------------
This is Line Three
--------------
This is Line Four
--------------
This is Line Five
--------------
--------------
即。在最后一行之后,我得到两条额外的线。再也无法弄清楚为什么会这样?
3)使用read
函数,我得到的尺寸是92
,其中文件中的字符总数为89
,包括EOF
},spaces
和'\n'
。最后一行在显示文件的最后一个字符后显示两个垃圾字符。为什么会这样?
cout << "\n\n$$$$$$$$$$$$$$\n\n";
is.clear();
is.seekg(0,ios_base::end);
int size=is.tellg();
is.seekg(0,ios_base::beg);
cout << "size : " << size << endl;
//char* readBuff = (char *) ::operator new(sizeof(char)*size);
char* readBuff = new char[size];
is.read(readBuff,size);
cout << readBuff;
delete(readBuff);
输出:
$$$$$$$$$$$$$$
size : 92
This is Line One
This is Line Two
This is Line Three
This is Line Four
This is Line Five▒u
由于
修改
根据Mats Peterson收到的Per Answer,我尝试了以下代码:
while(is.get(buff,50,'\n'))
{
cout << buff ;
//cout << "\n--------------\n";
is.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
//Flushing the is stream as '\n' was left by get fn
}
cout << "\n\n@@@@@@@@@@@@@@\n\n";
is.clear();
is.seekg(0,ios_base::beg);
// while(!is.eof())
while(is.getline(buff,50,'\n'))
{
cout << buff;
//cout << "\n--------------\n";
//No need to flush the is stream as '\n'
//was extracted and discarded by getline
}
但得到了输出:
###########
This is Line Fivee
@@@@@@@@@@@@@@
This is Line Fivee
即只有最后一行读取...如果我取消注释//cout << "\n--------------\n";
我得到正确的阅读
@Down Votes 至少评论是什么让你这样做的?我遇到了这个问题,这就是为什么要求专家提供更多见解的原因。
答案 0 :(得分:1)
在前两个问题中,你是因为你正在阅读“比你有更多的”,这是“在我们试图阅读结束之前未设置失败状态”的典型结果。这就是你应该使用
的原因 while(is.get(... ))
while(is.getline(...))
作为结束循环的条件 - 因为当读取失败时不会运行循环。
第三个问题是因为Windows使用“CR + LF”作为换行符,其中以文本模式(默认值)读取文件会将这些文件折叠为单个换行符。因此,根据is.tellg
的文件大小,每个换行符的大小比实际读取的数据大一个字符。您可以使用is.gcount()
查看您实际阅读的字符数。 (而if (!is.read(... )) actual = is.gcount(); else actual = size;
应该会给你一整段代码)。
答案 1 :(得分:0)
由于使用了eof(你已经使用过它),读取额外值或线的一个主要原因被称为垃圾值(我认为是这样)。当我们使用它时,例如,从文件中读取一个字符,然后它读取字符,但因为文件没有结束,循环也没有在点结束,所以它再次从文件中读取额外的值。所以我要说的主要是避免在任何循环语句中使用函数eof,直到结束文件读取而不是在任何输入输出条件下。