关于c++文件I/O和fstream的问题
a quesition about c++ file I/O and fstream
我需要打开一个文件并获取第一个 character.If 我用 ios::in 打开文件,当文件没有 exist.So 时它不会创建文件无法打开文件,我用 ios::out
打开文件,它会创建一个空文件,所以我可以在文件中输入“0”。
fstream passengerData;
passengerData.open("passenger.txt",ios::in);
if (!passengerData)
{
passengerData.open("passenger.txt",ios::out);
passengerData << '0' ;
passengerData.close();
}
当我运行 this in visual studio 2015
时,它可以在visual c++ 6.0
中工作well.But,它只能创建一个空文件,'0'不输入进入file.I 想知道为什么结果不同以及如何解决问题。
我还想知道当我使用 ios::in|ios::out
或 ios::in|ios::out|ios::app
.
时按位运算符 OR 是如何执行的
从 fstream::open
on cppreference 的文档看来,它似乎只是从 C++11 开始也打开了 clear()
成功标志,所以也许如果你在调用之前手动清除标志 open
调用也会在 VC++6:
中成功
fstream passengerData;
passengerData.open("passenger.txt",ios::in);
if (!passengerData)
{
passengerData.clear();
passengerData.open("passenger.txt",ios::out);
passengerData << '0' ;
passengerData.close();
}
此外,您还需要在第二次调用 open
后检查 passengerData
的状态。
MicroVirus 的预感是正确的。我想详细解释一下为什么什么都没发生。
基本上,当 passengerData.open("passenger.txt",ios::in);
设置 failbit
时。现在你确实用 passengerData.open("passenger.txt",ios::out);
重试了,它确实成功了(原文如此!),尽管错误位没有被清除(c++11 之前的行为),并使随后的 operator<<
什么都不做。
我想这是标准中的一个缺陷,vc++6 对于 c++11 来说太旧了。
cppreference 来源解释了行为:
您使用 operator<<
, which is a FormattedOutputFunction
表示:
A FormattedOutputFunction is a stream output function that performs the following:
Constructs an object of type basic_ostream::sentry with automatic storage duration, which performs the following:
- if
eofbit
or badbit
are set on the output stream, sets the failbit
as well [...]
因此它检查流 (passengerData
) 是否可操作。现在,有趣的是,eof
或 bad
位都没有设置,所以这似乎是一个错误的方法,但是下一步:
- Checks the status of the sentry by calling sentry::operator bool(), which is equivalent to
basic_ios::good
.
其中包含 eof-
、fail-
和 bad-
位。那些是 iostate
s。在 failbit 部分你可以找到:
The failbit is set by the following standard library functions:
- The constructors of std::basic_fstream, std::basic_ifstream, and std::basic_ofstream that takes a filename argument, if the file cannot be opened.
- basic_fstream::open, basic_ifstream::open, and basic_ofstream::open if the file cannot be opened.
您可以在第二次打开后检查 iostate
位来确认这一点:
fstream passengerData;
passengerData.open("passenger.txt",ios::in);
if (!passengerData)
{
passengerData.open("passenger.txt",ios::out);
if (passengerData.rdstate() & std::ios_base::fail) {
std::cout << "stream has failbit set\n";
}
passengerData << '0' ;
passengerData.close();
}
我需要打开一个文件并获取第一个 character.If 我用 ios::in 打开文件,当文件没有 exist.So 时它不会创建文件无法打开文件,我用 ios::out
打开文件,它会创建一个空文件,所以我可以在文件中输入“0”。
fstream passengerData;
passengerData.open("passenger.txt",ios::in);
if (!passengerData)
{
passengerData.open("passenger.txt",ios::out);
passengerData << '0' ;
passengerData.close();
}
当我运行 this in visual studio 2015
时,它可以在visual c++ 6.0
中工作well.But,它只能创建一个空文件,'0'不输入进入file.I 想知道为什么结果不同以及如何解决问题。
我还想知道当我使用 ios::in|ios::out
或 ios::in|ios::out|ios::app
.
从 fstream::open
on cppreference 的文档看来,它似乎只是从 C++11 开始也打开了 clear()
成功标志,所以也许如果你在调用之前手动清除标志 open
调用也会在 VC++6:
fstream passengerData;
passengerData.open("passenger.txt",ios::in);
if (!passengerData)
{
passengerData.clear();
passengerData.open("passenger.txt",ios::out);
passengerData << '0' ;
passengerData.close();
}
此外,您还需要在第二次调用 open
后检查 passengerData
的状态。
MicroVirus 的预感是正确的。我想详细解释一下为什么什么都没发生。
基本上,当 passengerData.open("passenger.txt",ios::in);
设置 failbit
时。现在你确实用 passengerData.open("passenger.txt",ios::out);
重试了,它确实成功了(原文如此!),尽管错误位没有被清除(c++11 之前的行为),并使随后的 operator<<
什么都不做。
我想这是标准中的一个缺陷,vc++6 对于 c++11 来说太旧了。
cppreference 来源解释了行为:
您使用 operator<<
, which is a FormattedOutputFunction
表示:
A FormattedOutputFunction is a stream output function that performs the following:
Constructs an object of type basic_ostream::sentry with automatic storage duration, which performs the following:
- if
eofbit
orbadbit
are set on the output stream, sets thefailbit
as well [...]
因此它检查流 (passengerData
) 是否可操作。现在,有趣的是,eof
或 bad
位都没有设置,所以这似乎是一个错误的方法,但是下一步:
- Checks the status of the sentry by calling sentry::operator bool(), which is equivalent to
basic_ios::good
.
其中包含 eof-
、fail-
和 bad-
位。那些是 iostate
s。在 failbit 部分你可以找到:
The failbit is set by the following standard library functions:
- The constructors of std::basic_fstream, std::basic_ifstream, and std::basic_ofstream that takes a filename argument, if the file cannot be opened.
- basic_fstream::open, basic_ifstream::open, and basic_ofstream::open if the file cannot be opened.
您可以在第二次打开后检查 iostate
位来确认这一点:
fstream passengerData;
passengerData.open("passenger.txt",ios::in);
if (!passengerData)
{
passengerData.open("passenger.txt",ios::out);
if (passengerData.rdstate() & std::ios_base::fail) {
std::cout << "stream has failbit set\n";
}
passengerData << '0' ;
passengerData.close();
}