C++,使用 ifstream 读取文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10680698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++, reading a file using ifstream
提问by Yoh0xFF
class Person {
private:
string firstName;
string lastName;
public:
Person() {}
Person(ifstream &fin) {
fin >> firstName >> lastName;
}
void print() {
cout << firstName
<< " "
<< lastName
<< endl;
}
};
int main() {
vector<Person> v;
ifstream fin("people.txt");
while (true) {
Person p(fin);
if (fin == NULL) { break; }
v.push_back(p);
}
for (size_t i = 0; i < v.size(); i++) {
v[i].print();
}
fin.close();
return 0;
}
Please can you explain me, how following code snippet works? if (fin == NULL) { break; }
请你能解释一下,下面的代码片段是如何工作的吗?如果(鳍 == NULL){ 中断;}
fin is a object on stack, not a pointer so it can not become NULL. I was unable to find overloaded operator== function in ifstream class. So I can not understand how this snippet works.
fin 是堆栈上的对象,而不是指针,因此它不会变为 NULL。我无法在 ifstream 类中找到重载的 operator== 函数。所以我不明白这个片段是如何工作的。
采纳答案by Greg Hewgill
The ifstream
class has an operator void *()
(or operator bool()
in C++11). This is what is called when you test (fin == NULL)
.
的ifstream
类有一个operator void *()
(或operator bool()
在C ++ 11) 。这就是您测试时所称的(fin == NULL)
。
Testing fin == NULL
should be exactly the same as testing fin.fail()
.
测试fin == NULL
应该与测试完全一样fin.fail()
。
回答by James Kanze
The base classes of istream
and ostream
have implicit conversion
functions, which allow them to be used as a boolean value; in pre-C++11,
the implicit conversion was to void*
.
的基类istream
和ostream
具有隐式转换功能,这允许它们被用作一个布尔值; 在 C++11 之前的版本中,隐式转换是void*
.
It was never the intent that the result of this conversion be used as a
pointer, and code like fin == NULL
shows an extremely poor
understanding of C++ and the standard streams. The idiomatic way of
writing the first loop would be to define a default constructor and an
operator>>
for Person
, and then write:
将这种转换的结果用作指针从来都不是意图,并且类似的代码fin == NULL
显示对 C++ 和标准流的理解非常差。编写第一个循环的惯用方法是定义一个默认构造函数和一个
operator>>
for Person
,然后编写:
Person p;
while ( fin >> p ) {
v.push_back( p );
}
(And while I'm at it: you really should test the return value of
fin.close()
, and not return 0
if it fails:
(当我在做的时候:你真的应该测试 的返回值
fin.close()
,0
如果失败就不要返回:
fin.close();
return fin ? EXIT_SUCCESS : EXIT_FAILURE;
.)
.)
回答by Konrad Rudolph
This isn't how streams are supposed to be used. True, this (unfortunately!) compiles and even does the “right” thing. But don't write code like this. Whoever wrote this code probably thought they were clever.
这不是应该如何使用流。确实,这(不幸的是!)编译甚至做了“正确”的事情。但是不要写这样的代码。编写此代码的人可能认为他们很聪明。
But what they really did was break the expectations of C++ programmers by introducing a new, unconventional API, with no real advantages.
但他们真正做的是通过引入一个新的、非常规的 API 来打破 C++ 程序员的期望,没有真正的优势。
This code initialises an object of type Person
from an input stream. Unfortunately, by doing this, the code forgoes the opportunity to test for errors while reading the object. This isn't good. An object should nothave a constructor accepting an input stream, it should overload operator>>
.
此代码Person
从输入流初始化类型对象。不幸的是,通过这样做,代码放弃了在读取对象时测试错误的机会。这不好。对象应该不具有构造接受输入流,但是应当过载operator>>
。