zoukankan      html  css  js  c++  java
  • [c++primer][08]标准IO库

    C++的输入/输出由标准库提供,支持对文件、控制窗口和string对象的读写。

    8.1 面向对象的程序库

    IO类型在三个独立的头文件中定义,iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,sstream所定义的类型用于读写存储在内存中string对象。

     

    如果函数有基类类型的引用形参时,可以给函数传递其派生类型的对象。即对istream&进行操作的函数,也可以使用ifstream或者istringstream对象来调用。

    标准库定义了一组相关类型,支持wchar_t类型,每个类都加上“w”前缀,与char类型的版本区分。如wiostream、wfstream、wstringstream等。

    IO对象不可复制或赋值

    1)流对象不能复制,故不能存储在vector等容器中;

    2)形参或返回类型不能为流类型。如要传递或返回IO对象,必须指定为该对象的指针或引用。

    8.2 条件状态

    条件状态

    badbit标志着系统级的故障,无法恢复;failbit是IO错误,通常可以修正;eofbit是在遇到文件结束符时设置的,此时同时设置了failbit

    bad、fail、eof中任意一个为true,则流处于错误状态;若三者都不为true,则good操作返回true。

    clear操作将条件重设为有效状态。

    setstate操作打开某个指定的条件,表示某个问题发生。

    流状态的查询和控制

    int ival;
    // read cin and test only for EOF; loop is executed even if there are other IO failures
    while (cin >> ival, !cin.eof()) {
        if (cin.bad()) // input stream is corrupted; bail out
            throw runtime_error("IO stream corrupted");
        if (cin.fail()) { // bad input
            cerr<< "bad data, try again"; // warn the user
            cin.clear(istream::failbit); // reset the stream
            continue; // get next input
        }
    // ok to process ival
    }    

    条件状态的访问

    rdstate成员函数返回一个iostate类型的值,表示流当前的整个条件状态。

    // remember current state of cin
    istream::iostate old_state = cin.rdstate();
    cin.clear();
    process_input(); // use cin
    cin.clear(old_state); // now reset cin to old state

    多种状态的处理

    使用按位或在一次调用中生成“传递两个或更多状态位”的值

    // sets both the badbit and the failbit
    is.setstate(ifstream::badbit | ifstream::failbit);

    生成一个值,对应于badbit和failbit的位都打开了,将这两个位都设置为1,该值的其他位都为0

    8.3 输出缓冲区的管理

    每个IO对象都管理一个缓冲区,用于存储程序读写的数据。下面几种情况会导致缓冲区的内容被刷新

    1)程序正常结束

    2)在一些不确定的时候,缓冲区已满,写入新数据前被刷新

    3)用操纵符显式地刷新缓冲区

    cout << "hi!" << flush; // flushes the buffer; adds no data
    cout << "hi!" << ends; // inserts a null, then flushes the buffer
    cout << "hi!" << endl; // inserts a newline, then flushes the buffer

    4)每次操作执行完后,用unitbuf操纵符设置流的内部状态,从而清空缓冲区

    cout << unitbuf << "first" << " second" << nounitbuf;
    //is equivalent to writing
    cout << "first" << flush << " second" << flush;

    unitbuf在每次执行完写操作后都刷新流,nonunitbuf操作符将流恢复为使用正常的、由系统管理的缓冲区刷新方式。

    5)将输出流与输入流关联,在读输入流时将刷新其关联的输出缓冲区

    标准库默认将cout与cin绑定在一起

    tie函数可用istream或ostream调用,使用一个指向ostream对象的指针形参。如果在调用tie函数时传递实参0,则打破该流上已存在的捆绑。

    cin.tie(&cout); // illustration only: the library ties cin and cout for us
    ostream *old_tie = cin.tie();
    cin.tie(0); // break tie to cout, cout no longer flushed when cin is read
    cin.tie(&cerr); // ties cin and cerr, not necessarily a good idea!
    // ...
    cin.tie(0); // break tie between cin and cerr
    cin.tie(old_tie); // restablish normal tie between cin and cout

    8.4 文件的输入和输出

    fstream除了继承下来的行为外,还定义了两个自己的新操作,open,close

    流对象的两种初始化形式

    // construct an ifstream and bind it to the file named ifile
    ifstream infile(ifile.c_str());
    
    ifstream infile; // unbound input file stream
    infile.open("in"); // open file named "in" in the current directory

    由于历史原因,IO标准库使用C风格字符串而不是C++ string类型的字符串作为文件名。

    检查文件打开是否成功

    // check that the open succeeded
    if (!infile) {
        cerr << "error: unable to open input file: "
            << ifile << endl;
        return -1;
    }

    将文件流与新文件重新捆绑(文件流改变关联文件时,需先关闭当前的文件流)

    ifstream infile("in"); // opens file named "in" for reading
    infile.close(); // closes "in"
    infile.open("next"); // opens file named "next" for reading

    清除文件流的状态

    重用已存在的流对象,while循环必须在每次循环时记得关闭和清空文件流,因成功打开文件并读取直到文件结束或出现其他错误为止,流对象处于错误状态,任何读取流对象的尝试都会失败。

    ifstream input;
    vector<string>::const_iterator it = files.begin();
    // for each file in the vector
    while (it != files.end()) {
        input.open(it->c_str()); // open the file
        // if the file is ok, read and "process" the input
        if (!input)
            break; // error: bail out!
        while(input >> s) // do the work on this file
            process(s);
        input.close(); // close file when we're done with it
        input.clear(); // reset state to ok
        ++it; // increment iterator to get next file
    }    

    文件模式

    in 读打开,ifstream默认方式

    out 写打开,ofstream默认方式,文件会被清空

    app  末尾写打开

    ate 打开定位到末尾

    trunc 清空打开

    binary 二进制形式打开

    一个打开并检查输入文件的程序

    // opens in binding it to the given file
    ifstream& open_file(ifstream &in, const string &file)
    {
        in.close(); // close in case it was already open
        in.clear(); // clear any existing errors
        // if the open fails, the stream will be in an invalid state
        in.open(file.c_str()); // open the file we were given
        return in; // condition state is good if open succeeded
    }

    8.5 字符串流

    stringstream对象的使用

    string line, word; // will hold a line and word from input, respectively
    while (getline(cin, line)) { // read a line from the input into line
        // do per-line processing
        istringstream stream(line); // bind to stream to the line we read
        while (stream >> word){ // read a word from line
            // do per-word processing
        }
    }

    stringstream提供的转换

    int val1 = 512, val2 = 1024;
    ostringstream format_message;
    // ok: converts values to a string representation
    format_message << "val1: " << val1 << "
    "
                              << "val2: " << val2 << "
    ";
    // str member obtains the string associated with a stringstream
    istringstream input_istring(format_message.str());
    string dump; // place to dump the labels from the formatted message
    // extracts the stored ascii values, converting back to arithmetic types
    input_istring >> dump >> val1 >> dump >> val2;
    cout << val1 << " " << val2 << endl; // prints 512 1024  

    使用输入操作符读string时,空白符将会忽略。

  • 相关阅读:
    绝对均匀图生成算法
    告别S! S! H! 秒杀终端工具——FastLogin快捷登录
    使用Atom打造无懈可击的Markdown编辑器
    程序异常分析指南
    javascript opacity兼容性随笔
    javascript event兼容性随笔
    javascript Xml兼容性随笔
    addEventListener、attachEvent、cancelBubble兼容性随笔
    算法--逆波兰表达式(数学逆波兰表达式和交并集逆波兰表达式)
    算法--区间数据计算
  • 原文地址:https://www.cnblogs.com/itree/p/4818018.html
Copyright © 2011-2022 走看看