提问人:Abhishek Mane 提问时间:10/24/2021 最后编辑:PreethiSamanthaBennetAbhishek Mane 更新时间:11/4/2021 访问量:754
当我们尝试提取文件中的行时,实际会发生什么,之后 'eof' 字符与 istream::getline() 和 std::getline() 一起出现
What's actually happens when we try to extract line in file after which `eof` character is present with istream::getline() and std::getline()
问:
roha.txt
I really love to spend time with you.
Let's go for coffee someday.
Enjoy whole day and cherish the memories.
代码-1
#include <iostream>
#include <fstream>
int main()
{
char str[100];
std::ifstream fin;
fin.open("roha.txt", std::ios::in);
for(int i=0; i<=3; i++)
{
std::cout<<bool(fin.getline(str,100) )<<" "<<str<<fin.fail()<<"\n";
}
}
输出
1 I really love to spend time with you.0
1 Let's go for coffee someday.0
1 Enjoy whole day and cherish the memories.0
0 1
代码-2
#include <iostream>
#include <fstream>
#include <string>
using std::string;
int main()
{
string str;
std::ifstream fin;
fin.open("roha.txt", std::ios::in);
for(int i=0; i<=3; i++)
{
std::cout<<bool(std::getline(fin,str) )<<" "<<str<<fin.fail()<<"\n";
}
}
输出
1 I really love to spend time with you.0
1 Let's go for coffee someday.0
1 Enjoy whole day and cherish the memories.0
0 Enjoy whole day and cherish the memories.1
我知道 和 是不同的。但我想知道到底发生了什么。C-style char array
istream::getline
string
std::getline
我猜对于 ,它提取了第 1 次、第 2 次的字符串,当它尝试提取它看到的第 3 次时,它会在 .string
std::getline
eof
eof
下次我们尝试提取它时,只是遇到,所以它没有提取任何东西并设置.eof
fail-bit
string str
没有被修改,所以当我们尝试打印它时,只有最后提取的字符串才会被打印出来。
我不知道我的想法是否正确......
我也不能对 .istream::getline()
C-style char array
答:
引用该标准,第 21.3.3.4 节插入器和提取器 [string.io]:
条款 6:
[...]构造对象后,如果 转换为 ,则调用并提取字符并将其附加到 [...] 中,直到发生以下任一情况:
sentry
sentry
true
str.erase()
is
str
- 文件末尾发生在输入序列上(在这种情况下,函数调用 .
getline
is.setstate(ios_base::eofbit))
- [...]
第 29.7.4.1.3 节 类:basic_istream::sentry
explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);
效果:如果是,则调用 [...] 如果,在完成任何准备工作后,是 ,否则,.在准备过程中,构造函数可以调用 [...]is.good()
false
is.setstate(failbit)
is.good()
true
ok_ != false
ok_ == false
setstate(failbit)
explicit operator bool() const;
返回:ok_
那么,字符串版本发生了什么:
- 提取最后一个字符串。这将设置 eofbit,但不设置 failbit
- 你又得到线了
- getline 构造哨兵
- 哨兵检查.这是假的,因为设置了 eofbit
is.good()
- 哨兵设置故障位并将其成员ok_设置为 false
- getline 函数检查哨兵是否为 true(运算符布尔)。这是错误的
- getline 函数在清除旧字符串之前返回
部分 29.7.4.3 未格式化的输入函数
第 21 条(这是关于 C 字符串版本):
在任何情况下,如果大于零,则它将 null 字符 (using ) 存储到数组的下一个连续位置
n
charT()
其余的措辞类似于字符串版本。换句话说,getline 的 C 字符串版本始终存储一个字符,即使它失败了。该版本没有,大概是因为如果您忘记检查故障位,它不会引入与 C 版本相同的内存安全问题。'\0'
std::string
评论
getline()
failbit
eof
string str
getline(istream, string)
char str[100]
cin.getline(str,n)
评论
std::ifstream fin; fin.open("roha.txt", std::ios::in);
std::ifstream fin("roha.txt", std::ios::in);
ifstream
std::ifstream("roha.txt");
std::cout << f() << g();
f()
g()
g()
f()
fin.fail()
fin.getline(str, 100)
fin.fail()
fin.getline(str, 100)
getline()
fin.getline(str, 100);
getline
bool(fin)
while (fin.getline(str, 100))
getline