zoukankan      html  css  js  c++  java
  • C++中IO流

    一、使用流

     1、到底什么是流

       cout和cin都是在C++的std命名空间中预定义的流实例。

       每个输入流都有一个相关联的源,每个输出流都有一个相关联的目的。

     2、流的源和目的

       控制台流、文件流、字符串流,还有比如打印机输出或网络I/O是由操作系统提供的,并没有内置到C++语言中。

     3、流输出

       ①、cout流是把数据写到控制台或者标准输出的内置流。

       ②、C++流可以正确地解析C风格的转义代码,比如包含\n的字符串,但是这样的情况下,内置的endl机制会更好。使用endl用于表示行结束字符并刷新输出缓冲区。

       put()和write()是原始的输出方法,它们是cout提供的公共方法。

       向输出流写数据时,流不必立刻把数据写到目的中,大部分的输出流都会进入缓冲区,或累积数据,而不是数据一到来就写出。当下列条件之一发生时,流会刷新输出,或者写出累积的数据:

    ·      到达一个标记,比如endl标记。

    ·      流超出作用域,因此被撤销。

    ·      对应的输入流请求输入(也就是,cin输入时,cout会刷新输出)

    ·      流缓冲区已满

    ·      明确告诉流要刷新输出其缓冲区(flush()方法)

       注:不是所有的流都会缓冲,cerr流就没有对其输出进行缓冲。

      

    ①、处理输出错误

    ·      good()函数:在流上直接调用good()来确定流当前是否是好的(或的流的有效性基本信息)

    ·      bad()函数:返回true表示发生了一个致命的错误。

    ·      fail()函数:如果最近的操作失败,它会返回true,意味着下一个操作也会失败。

    ·      clear()函数:重置流的错误状态。

    ②、输出控制符

     控制符是一些对象,他们可以改变流的行为。

     <iomanip>:setw和setfill、<iostream>头文件包含。

     

     4、流输入

       输入流提供了一种读取结构化或非结构化数据的简单方法。

       和输出流一样,输入流也提供了一些方法来完成更底层的访问:

    ·      get():允许从流输入原始数据。

    ·      unget():unget()调用会引起流后退一个位置,其本质是把最后一个字符读回到流中。

    ·      puthack():允许在输入流中后退一个字符,putback()方法取流中要后退的字符作为参数。

    ·      peek():peek()方法允许预览下一个值。

    ·      getline():方法getline()使用一行不超过指定长度的数据来填充一个字符缓冲区,所得到的字符串不包括换行字符。

        处理输入错误

        输入控制符

        例:boolalpha、noboolapha、hex、oct、dec、skipws、noskipws、ws。

     

    5、 输入和输出对象

     在C++中,对象可以预定如何进行输入输出,通过重载操作符<<,使之了解如何输出一个新类型或类来做到。

     

    二、字符流

     流具有内置的词法分析功能,所以字符串流对于解析文本也很有用处。

     类ostringstream和istringstream分别用于向字符串写数据和从字符串读数据。它们都定义在头文件<sstream>中。 

     

    三、文件流

     文件非常适合于流抽象,因为除了数据之外,读写文件总是会涉及到位置。

     C++中,类ofstream和ifstream提供了文件的输入输出功能,定义在头文件<fstream>中。

     参考代码: 

    /**//*

     *NOTE: file_stream.cpp - file stream test...

     * 

     */

     

    #include <fstream>

    #include <string>

    #include <iostream>

    using namespace std;

    int main(int argc, char *argv[])

    ...{

        /**//* create file stream. */

        ofstream fout("file_stream.txt");

        

        if (!fout.good()) ...{

            cerr << "error opening file_stream.txt for writing. ";

            exit(1);

        }

        

        /**//* Output the string "name = lulixue" */

        fout << " [name]=lulixue";

        

        /**//* Verify that the marker is at the end. */

        streampos curPos = fout.tellp();

        

        if (curPos) ...{

            cout << "Test passed: Currently at position 6." << endl;

        } else ...{

            cout << "Test failed: Not at postion 6." << endl;

        }

        

        /**//* Move to position 2 in the stream */

        fout.seekp(2, ios_base::beg);

        

        fout << 'N';

        fout.flush();

        

        ifstream fin("file_stream.txt");

        

        if (!fin.good()) ...{

            cout << "Error opening file_stream.txt for reading. ";

            exit(1);

        }

        

        /**//* Read the file string */

        string file_str;

        fin >> file_str;

        string strMacth = "[Name]=lulixue";

        cout << "strMacth: " << strMacth << endl;

        cout << "file_str: " << file_str << endl;

        if (file_str == strMacth) ...{

            cout << "Test passed: Value is [Name]=lulixue" << endl;

        } else ...{

            cout << "Test failed: Vlaue is not [Name]=lulixue";

        }

        

        return 0;

    }

     

       Ø    链接流:可以在任何输入流和输出流之间建立连接,也即,从输入流请求数据时,与其链接的输出流会自动刷新输出。

       Ø    链接流用方法tie()来实现。要把输出流绑定到一个输入流中,可以在输入流上调用   tie(),并把输出流的地址传递给它。要断开这个连接,传递NULL即可。

       Ø    也可以把一个输出流链接到另一个输出流上。

       例:outFile.tie(&antherOutFile);,这样,每次向第一个文件写数据时候,就会向另一个文件写入已经发送的缓冲数据,可以用这种机制保持两个相关文件之间的同步。

     

    四、双向I/O

       有一种流可以同时进行输入输出,双向流可以同时作为输入流和输出流操作。

       双向流是iostream的子类,所以也是istream和ostream的子类,因此可以作为一个有用的多重继承的例子。双向流同时支持>>和<<操作符,还支持输入流和输出流方法。

       fstream类提供了一个双向的文件流,如果应用需要替换一个文件中的数据,fstream就非常理想,因为找到正确的位置之前可以一直完成读操作,找到之后立即切换为写操作。

       只有数据长度固定时,这样的方法才能正常工作。

       同过string stream类,也可以以双向方式访问字符串流。

       注:双向流对于读位置和写位置分别由单独的指针,在读操作与写操作之间切换时,需要查找到正确的位置。 

       实例代码: 

    /**//*

     * bidirectional_stream.cpp - bidirectional file stream test...

     */

    #include <iostream>

    #include <fstream>

    #include <string>

    using namespace std;

    void change_number_for_id(const string& in_file_name,  int id, const string& in_new_number)

    ...{

        cout << "3" << endl;

        fstream io_data(in_file_name.c_str());

        if (!io_data) ...{

            cerr << "Error while opening file " << in_file_name << endl;

            exit(1);

        }

        while (io_data.good()) ...{

            int id_feild;

            string number;

            //Read the next ID

            io_data >> id_feild;

            //Check to see if the current record is the one being changed.

            if (id_feild == id) ...{

                //Seek to the current position.

                io_data.seekp(io_data.tellg());

                //Output a space, then the new number

                io_data << " " << in_new_number;

                break;

            }

            //Read the current number

            io_data >> number;

        }

        cout << "4" << endl;

    }

    int main(int argc, char *argv[])

    ...{

        string str_file_name = "bidirectional_input.txt";

        string str_number    = "111-222-3333";

        cout << "1" << endl;

        change_number_for_id(str_file_name, 333, str_number);

        cout << "2" << endl;

        return 0;

  • 相关阅读:
    针对图片性能优化的总结
    activityGroup源码分析
    针对BaseAdapter的扩展
    ADB命令介绍
    一个对内存分析的文章。 非常棒。
    hdu 1285 确定比赛名次(很典型的拓扑排序)
    经典排序之归并排序
    hdu 1166 敌兵布阵 (树状数组)
    hdu 3518 Boring counting (后缀数组)
    hdu 3584 Cube(树状数组)
  • 原文地址:https://www.cnblogs.com/dancingrain/p/3405234.html
Copyright © 2011-2022 走看看