zoukankan      html  css  js  c++  java
  • 【转载】C++ IO库

    本篇随笔为转载,原贴地址:《C++ Primer》第8章 IO库 学习笔记

    1.IO类

     1 #include <iostream>
     2 istream//从流中读取数据
     3 ostream//从流中写入数据
     4 iostream//读写流
     5 
     6 #include <fstream>//文件
     7 ifstream
     8 ofstream
     9 fstream
    10 
    11 #include <sstream>//字符串
    12 istringstream
    13 ostringstream
    14 iostringstream

    fstream和sstream都继承于iostream,所以iostream有的操作他们都有。

    另外流前面加字母w表示针对宽字符。

    2.IO对象无拷贝和赋值

    1 ostream o1,o2;
    2 o1 = o2;
    3 ostream o3(o1);

    错误,不能拷贝和赋值

     因为流不能拷贝和赋值,所以流作为函数参数或者是返回值必须是引用类型,且读写一个IO对象会改变其状态,

    因此传递和返回的引用不能是const的

    就好像

    const成员函数不可改变对象内容,同时也不可通过函数返回值改变对象内容。 所以返回指向对象的指针

    或引用都会被编译器拦住的。 const指针或const引用不会改变对象内容,所以可以返回。

    3.IO条件状态

    1 strm代表一种IO类型,流处于好的状态时这些bit位全部处于0。
    2 
    3 strm::iostate   iostate一种机器相关类型,提供了表达条件状态的完整功能
    4 strm::badbit    指出流已经崩溃
    5 strm::failbit   指出IO操作失败
    6 strm::eofbit    指出流达到了文件的末尾
    7 strm::goodbit   指出流处于未错误状态
    1 s.eof()          若流处于eofbit,返回true
    2 s.fail()         若流处于failbit,返回true
    3 s.bad()          若流处于badbit,返回true
    4 s.good()         若流处于有效状态,返回true
    5 s.clear()        将流所有状态恢复,设置为有效,返回void
    6 s.clear(flag)    将指定bit位恢复,设置为有效,返回void。flag类型为strm::iostate
    7 s.setstate(flag) 根据给定的bit标志位,将流s中对应条件状态位置位。flag类型为strm::iostate
    8 s.rdstate()      读取当前的状态

    例子:

     1 #include <iostream>
     2 #include <fstream>
     3 
     4 using namespace std;
     5 
     6 istream& read(istream& is)
     7 {
     8     int i;
     9     while(is >> i && i != EOF)         
    10     {
    11         cout << i << endl;
    12     }
    13     cout << "eof:" << is.eof() << endl;    
    14     cout << "fail:" << is.fail() << endl;
    15     cout << "bad:" << is.bad() << endl;
    16     cout << "good:" << is.good() << endl;
    17     cout << "rdstate " << is.rdstate() << endl;
    18     
    19     cout << endl;
    20 
    21     //is.clear();和下面等价
    22     is.clear(is.rdstate() & ~is.failbit & ~is.eofbit);
    23     //is.setstate(is.eofbit);设置了后,rdstate()结果是2
    24 
    25     cout << "eof:" << is.eof() << endl;
    26     cout << "fail:" << is.fail() << endl;
    27     cout << "bad:" << is.bad() << endl;
    28     cout << "good:" << is.good() << endl;
    29 
    30     cout << endl;
    31     cout << "rdstate " << is.rdstate() << endl;
    32     
    33     return  is;
    34 }
    35 
    36 int main()
    37 {
    38     read(cin);
    39 
    40     return 0;
    41 }

    结果,上面是未注释掉is.setstate(is.eofbit);的结果

     下面是注释掉的结果:

    还有一种可以保存流当前状态,清空,然后再恢复。

    1 auto old_state = is.rdstate( );
    2 is.clear( );
    3 is.setstate(old_state);

    4.管理缓冲区

    1 #include <iostream>
    2 using namespace std;
    3 
    4 int main()
    5 {
    6     cout << "hi!" << endl;
    7     cout << "hi!" << ends;   //缓冲区插入一个字符,然后刷新
    8     cout << "hi!" << flush;  //刷新缓冲区,不输出任何字符
    9 }

    5.关联输入输出缓冲区

     任何试图从输入流读数据的操作都会先刷新关联的输出流。

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int i;
     7     cin >> i;                    //刷新cout 和 cerr;
     8     ostream *old_str;    
     9     old_str = cin.tie(nullptr);  //解开流,传递一个空指针。返回旧解
    10     ostream &os = cout;          //新建一个流
    11     cin.tie(&os);                //绑定这个新流
    12     cin >> i;
    13     cin.tie(old_str);            //恢复以前的状态
    14 }

    6.文件的输入和输出

    头文件定义了三种IO

    ifstream从文件中读取数据

    ofstream向一个文件写数据

    fstream可以读写

     1 //open:流用open和文件关联起来,如果open失败,failbit会被置位。因为open可能会失败,所以检查流是个好习惯
     2 //close:当将流文件关联到另外一个文件时,必须用close关闭当前的文件。
     3 
     4 #include <iostream>
     5 #include <fstream>
     6 #include <string>
     7 
     8 using namespace std;
     9 
    10 std::istream& read(std::istream& is, std::string& s) //不写引用就成为了副本
    11 {
    12     is >> s;
    13     return is;
    14 }
    15 
    16 std::ostream& print(std::ostream& os, std::string& s)//可以向iostream传递fstream,因为是派生类,不过对文件最好使用fstream
    17 {
    18     os << s;
    19     return os;
    20 }
    21 
    22 
    23 int main(int argc, char *argv[])
    24 {
    25     std::ifstream input(argv[1]);
    26     std::ofstream output(argv[2]);
    27 
    28     std::string s;
    29     read(input, s);
    30     std::cout << s << std::endl;
    31     print(output, s);
    32     std::string ss;
    33     //std::getline(ss, argv[1]);  读取一行
    34     std::cin >> ss;
    35 
    36     std::string ifile = "file2";
    37     std::ifstream in(ifile);    //新建一个文件流,并且初始化,初始化意味着open()
    38     std::ofstream out;
    39     out.open(ifile + ".copy");  //调用open()
    40     if(out);                    //如果流没错
    41     out << ss;
    42     out.close();                //没有close()下面error         close关闭流,一个流不能重复打开多个文件
    43     out.open("file");
    44     if(out)
    45         std::cout << out.good() << endl;
    46     else
    47         std::cerr << "error" << std::endl;
    48 } 

    课后题8.5

     1 #include <iostream>
     2 #include <fstream>
     3 #include <string>
     4 #include <vector>
     5 
     6 using namespace std;
     7 
     8 int main(int argc, char *argv[])
     9 {
    10     string s;
    11     fstream input(argv[1]);
    12     vector<string>ivec;
    13 
    14     while(!input.eof())//如果去掉if(input.fail())末尾会多输出一次
    15     {
    16         input >> s;
    17         if(input.fail())
    18         {
    19             cout << "fail " << endl;
    20             break;
    21         }
    22         ivec.push_back(s);
    23     }
    24 
    25     for(string &s : ivec)
    26     {
    27         cout << s << endl;
    28     }
    29 }

     没有if(input.fail( ))检查时,末尾总是会多输出一次文件末尾的内容。

     看代码,文件每次读取到s中,然后push_back(s),当文件读取到最后一次时(它自己不知道读取到最后了),push_back(s)后再次读取,

     发现到达末尾了,此时s中依然存着上一次的内容,push_back(s)后退出循环,所以最后一行s被push了两次,输出时当然输出两遍了。

    7.文件模式

    1 fstream fs("文件名", mode); //mode就是文件模式
    2  
    3 in         以读的方式打开
    4 out        以写的方式打开     
    5 app        每次写操作前均定位到末尾
    6 ate        打开文件后立刻定位到文件末尾
    7 trunc      截断文件
    8 binary     以二进制方式IO

    <1.只对ofstream或fstream设置out模式,out模式打开会丢弃已有数据

    <2.只对ifstream或fstream设置in模式

    <3.只有当out也被设定时才可以设定trunc模式

    <4.只要trunc模式没被设定,就可以设定app模式,在app模式下即使没有规定out也默认为out模式

    <5.没有指定trunc,以out打开也会截断文件,除非指定app,或同时打开in模式

    <6.ate和binary可以用于任何类型的文件流对象,且可以和其他任何文件模式组合。

    <7.每次调用open都可以指定文件模式。

    8.sstream流

    1 三个IO
    2 istringstream
    3 ostringstream
    4 stringstream
    5 特有操作
    6 sstream strm;       strm是一个未绑定的stringstream对象
    7 sstream strm(s);    strm是一个sstream对象,保存s的一个拷贝,此构造函数是explicit的
    8 strm.str();         返回strm所保存的string的拷贝
    9 strm.str(s);        将string s拷贝到strm中,返回void

    使用istringstream流

     istringstream读字符串时遇见空格算一个字符串,就可以读一个句子的单词。

     1 #include <iostream>
     2 #include <vector>
     3 #include <sstream>
     4 #include <string>
     5 #include <fstream>
     6 
     7 using namespace std;
     8 
     9 class record
    10 {
    11     public:
    12         string name;
    13         vector<string>phone;
    14 };
    15 
    16 int main(int argc, char *argv[])
    17 {
    18     ifstream input(argv[1]);
    19     string s;
    20     vector<record>Info;
    21     while(getline(input, s))
    22     {
    23         record re;
    24         istringstream is(s);
    25         is >> re.name;
    26         cout << "eof" << is.eof() << endl;
    27         while(!is.eof())  //while(is >> s)另外一种方法,不用测试eof,且注意eof成立为1
    28         {
    29             string s;
    30             is >> s;
    31             re.phone.push_back(s);
    32         }
    33         Info.push_back(re);
    34     }
    35 
    36     for(record &rec : Info)
    37     {
    38         cout << rec.name << " ";
    39         for(string &ph : rec.phone)
    40         {
    41             cout << ph << " ";
    42         }
    43         cout << endl;
    44     }
    45 }

    使用ostringstream流

    ostringstream流里面可以保存字符串的拷贝。需要时输出。

    比如检查一个字符串是否正确,正确的保存到流里,不正确的不保存,等到结束时输出全为正确的。

    1     string st = "asdasdasdasd";
    2     string st1;
    3     ostringstream os;
    4     os << " " << st<< endl;         //都写到了流里面
    5     os << " " << st << endl;
    6     cout << os.str() << endl;       //输出字符串流里面保存的字符串,返回                          字符串的拷贝
    7     os.str("");                     //使用前清空
    8     os.str(st);
    9     cout << os.str() << endl;        

    小结:

    1.iostream处理控制台IO

    2.fstream处理命名文件IO

    3.stringstream完成内存string的IO

    4.类fstream和sstream都继承自iostream,所以iostream的操作这些类也可以。

    5.每个流都有一组条件状态,保证流正确无误的使用就要保证流的状态正确无误

    6.为什么可以while(cin)来判断流状态,因为cin对象中重载了bool转换操作,如operator bool(),所以cin才能够参加布尔运算.

  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    108. Convert Sorted Array to Binary Search Tree
    111. Minimum Depth of Binary Tree
    49. Group Anagrams
    使用MALTAB标定实践记录
    442. Find All Duplicates in an Array
    522. Longest Uncommon Subsequence II
    354. Russian Doll Envelopes
    opencv 小任务3 灰度直方图
    opencv 小任务2 灰度
  • 原文地址:https://www.cnblogs.com/niuxichuan/p/5839314.html
Copyright © 2011-2022 走看看