当一个 ofstream object.open() 被注释掉时会发生什么

What happens when an ofstream object.open() is commented out?

本文关键字:注释 什么 open 一个 ofstream object      更新时间:2023-10-16
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
int main(){
    ofstream out;
    ifstream in;
    out.open("The Necessary Death of Charlie Countryman2.srt");
        if (out.fail()) {
            perror("The Necessary Death of Charlie Countryman2.srt");
        }
    in.open("The Necessary Death of Charlie Countryman.srt");
        if (in.fail()) {
            perror("The Necessary Death of Charlie Countryman.srt");
        }
    vector<string> input;
    string inc;
    while (getline(in, inc)) {
        input.push_back(inc);
    }
    for (int k = 0; k < input.size(); k++) {
        out << input[k] << endl;
    }    
    return 0;
}

当我从某个文件中读取时.txt使用 ifstream in 并写入另一个文件.txt使用 ofstream in,一切正常,但假设我注释掉out.open("anotherfile.txt")并执行代码,没有错误,当我打开另一个文件.txt它是空的。

我的问题是在

for (int k = 0; k < input.size(); k++) {
            out << input[k] << endl;
        }

会发生什么?

input[k]发送到哪里或发送到什么?如果是cout,它会转到命令提示符,如果没有注释out.open("anotherfile.txt")则转到另一个文件.txt。

我假设out被声明为ostream(或ofstream这样的子类(。注释掉行out.open(...)时,out初始化为关闭文件。因此,当您尝试写入它时,没有任何反应,并且注入失败......但是无法测试它是否成功!

如果您使用以下命令对其进行测试:

    for (int k = 0; k < input.size(); k++) {
        out << input[k] << endl;
        if out.fail() {
            // process error condition...
        }
    }

您将传入错误条件分支,并且能够知道注入未发生。

每个<<操作都失败,仅此而已(这就是(1(发生的所有情况(。


(1( 可以将流设置为在失败时引发异常的模式,但这不是默认值。默认情况下,失败只是静默忽略。除了设置了失败状态位,您可以使用fail()或通过转换为bool来检查。

ofstream使用此operator<<签名

basic_ostream& operator<<( std::basic_streambuf<CharT, Traits>* sb);

来自 cppp偏好, operator<< , 8(

构造并检查哨兵对象后,检查 sb 是否为空指针。如果是,则执行 setstate(badbit( 并退出。

您可以通过执行以下操作轻松检查

#include <iostream>
#include <fstream>
int main()
{
    std::ofstream sink;
    //sink.open("/dev/null");
    sink << "check state";
    switch(sink.rdstate())
    {
        case std::ios_base::failbit:
            std::cout << "stream state is failbitn";
            break;
        case std::ios_base::goodbit:
            std::cout << "stream state is goodbitn";
            break;
        case std::ios_base::eofbit:
            std::cout << "stream state is eofbitn";
            break;
        case std::ios_base::badbit:
            std::cout << "stream state is badbitn";
            break;
        default:
            break;
    }
    return 0;
}

打印:流状态为坏位

outstd::ostream 类型的对象,类似地std::cout是位于全局命名空间中的 std::ostream 类型的对象(它在程序的开头可用(。

类型为 std::ostream 的对象(输出流,包括像 std::ofstream 一样扩展它的子类(的 << 运算符重载。

这样拥有cout<<"hello";std::cout.operator<<("Hello World");是一回事

请注意,重载的 << 运算符返回对 ostream 对象的引用cout<<"hi" << " there";因此基本上

std::cout.operator<<("hi").operator<<(" there"));

您需要在写入任何输出文件流之前打开它。通过这样做,您将调用对操作系统的系统调用,该操作系统允许您访问文件,以便您可以写入它们。否则,您正在尝试写入进程无权写入的已关闭文件。

您不必为std::cout显式执行此操作,但您应该打开自己的输出文件流。

不要忘记关闭打开的文件!!