C++ primer之第八章(IO库 )



知识点:
    1. C++总体来说有三种输入输出流:第一种标准的输入输出,第二种是文件的输入输出,第三种是基于字符串的输入输出。 C++引入IO流,将这三种输入输出流接口统一起来,使用>>读取数据时,不用去管是从何处读取字符,使用<<写数据的时候也不需要管是写到哪里去。

    2. cin(cout) 是一个实例化的istream(ostream)对象,从标准输入(输出)读取(写入)数据。实例化在main函数之前。

    3. 不能对IO对象进行拷贝或赋值。因此不能将形参或返回类型设置为流类型,进行IO操作的函数通常以引用 方式传递和返回流。读写一个IO对象会改变其状态,因此传递和返回的引用不能是const的。

    4. IO类所定义的一些函数和标准,可以帮助我们访问和操纵流的条件状态。

    5. 一个流一旦发生错误,后续的IO操作都会失败。只有当一个流处于正确状态时,我们才可以从它读取数据,向它写入数据。确定一个流对象的状态最简答的办法是将它当作一个条件来使用,如while(cin>>word)

    6. 实际上,我们将流当作条件使用的代码就等价于!fail()。

    7. 导致缓冲刷新的原因有很多:缓冲区满,流状态设定,程序结束时,endl等操作符。

    8. 关于endl: 完成换行并刷新缓冲区的工作。 flush:只刷新缓冲区,不做任何操作。    ends:输出空字符并刷新缓冲区。

    9. 如果程序异常终止,输出缓冲区是不会被刷新的。当一个程序奔溃后,它所输出的数据很可能停留在输出缓冲区中等待打印。

    10. 头文件fstream定义了三个类型来支持文件IO:ifstream从一个给定的文件读取数据,ofstream向一个给定文件写入数据,fstream可以读写给定文件。

     11. fstream 是头文件 中定义的一个类型, 有很多的特有操作,当我们想读写一个文件时,可以定义一个文件流对象,并将对象与文件关联起来。每个文件流类都定义了一个名为open的成员函数,它来定位给定的文件,并按照情况打开读或写模式。创建文件流对象时,我们可以提供文件名。如果提供了一个文件名,则open会被自动调用。解释下: fstream fstrm; 创建一个未绑定的文件流(对象),可以随后调用open将它与文件关联起来。而 ifstream  fstrm( fName)变直接调用绑定到fName文件并自动调用open函数。

    12. 类型ifstream 和 istringstream 都继承自istream。

    13. 因为调用open 函数可能失败,通常进行open是否成功的检测 。

    14.当一个fstream 对象被销毁时,close 函数会自动被调用。

    15. fstream 类中有一个构造函数 fstream fileName(s,mode) mode 是关联的文件模式,按指定的 mode 打开文件,默认是依赖于fstream 类型(一般有in:以读方式; out :以写方式等等...)。 默认模式:与ifstream 关联的文件默认以in模式打开; 与ofstream 关联的文件默认以out 模式打开; 与fstream 关联的文件默认以 in 和out 模式打开。
    16. ofstream 默认的out 打开方式会阶段文件,唯一保留数据方式是显示指定 app 或 in 模式。

    17. 每次打开文件时,都要设置文件模式,可能是显式地设置,也可能是隐式地设置。未指定时,采用默认方式。

    18. 关于cin>>ci; cin 本身是输入流对象,1 通过键盘获取数据,2 通过>> 流提取运算符(读入)数据,3 将数据赋给ci变量。           
          而cout << co; cout是输出流对象,1通过<< 流插入运算符,将数据插入到cout输出流中,2 在将数据从输出流对象中输出到指定设备(屏幕)。因为cin和cout是与键盘屏幕等连接的所以,输入输出便指这两样。而8_07,8_08,是自定义的fstream对象,可以从一个文件读入数据,将数据打印(写)打印到另一个文件中。

    19. string 流 :sstream头文件定义了三个类型来支持内存IO,可以向string写数据,读数据;看起来string是以IO流一样。有一些独有的操作: sstream strm(s); strm 是一个sstream对象,保存string s的一个拷贝,此构造函数是explicit。strm.str(); 返回strm所保存的string(s)的拷贝.

    20. isotream 处理控制台IO; fstream 处理命名文件IO; stringstream 完成内存string 的IO; 而类fstream 和stringstream 都是继承自类 iostream 的。所以在iostream 对象上执行的操作,也可以在 fstream 和 stringstream 操作。

    21 每个IO 对象都维护一组条件状态,用来指出此对象上是否可以进行IO操作。如果遇到了错误——例如再输入流上遇到文件末尾,则对象的状态变为失效,所有后续输入操作都不能执行,直至错误被纠正。标注库提供了一组函数,用来设置和检测这些状态。



习题:
    8.03 答:当流的状态出错时,即eof, bad,fail 显示出错的标志时。
    8.12 答:暂时没想好怎么回答。
    8.14 答:entry与nums都不是内置类型,没有定义相应的拷贝函数,用引用快,安全。不允许被修改用户的数据,所以加const。



程序题:
题:8_01,  8_04,   8_05
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
//返回类型和形参都为istream&,返回对流状态复位
istream &fun8_01(istream &c)
{
     string st;
     c>>st;
     cout<<st<<endl;
     c.clear();
      return c;
}
//从文件读入数据,并存储到vector中
void fun8_04( const string &fName, vector<string> &svec1)
{
     string cs;
     ifstream f1(fName);
      if (f1) //注意加判断
     {
            while (getline(f1,cs))
           {
                svec1.push_back(cs);
           }
     }
}
//8.04的基础上将每个元素独立存储
void fun8_05( const string fname, vector<string> &svec2)
{
     fstream f2(fname);
     string word;
      if (f2)
     {
            //f2是个流对象, 可以对比cin,不过cin是面向键盘,f2是连接该文件,所以>>
            //是f2流往word变量里一个一个忽略空格回车,输出单词
            while (f2>>word)
                svec2.push_back(word);
     }
}
int main( int argc, char *argv[])
{
     
      //cout<<fun8_01(cin).rdstate();
     vector<string> svec;
     
      //fun8_04("D:/abc.txt",svec);这里地址注意是以/划分,而不是拷贝而来的\。
     
      int i = 0;
     fun8_05( "D:/abc.txt" ,svec);
      for ( auto it = svec.begin(); it!=svec.end(); ++it)
     {
           ++i;
           cout<< "第" <<i<< "词 :" <<*it<<endl;
     }
      return 0;
}
题:8_06
#include <fstream>
#include "D:/Sales_data.h"  
int main( int argc, char *argv[])
{
     ifstream input( "D:/abc.txt" );
     Slaes_data total;
    if (read(input, total)) {
        Slaes_data trans;
        while (read(input, trans)) {
            if (total.isbn() == trans.isbn())
            else {
                prin(std::cout, total) << std::endl;
                total = trans;
            }
        }
        prin(std::cout, total) << std::endl;
    }
    else {
        std::cerr << "No data?!" << std::endl;
    }
      return 0;
}
题:8_07,  8_08
#include <fstream>
#include "D:/Sales_data.h"  
int main( int argc, char *argv[])
{
     ifstream input( "D:/abc.txt" );
     ofstream output( "D:/cba.txt" , ofstream::app);
     Slaes_data total;
    if (read(input, total)) {
        Slaes_data trans;
        while (read(input, trans)) {
            if (total.isbn() == trans.isbn())
            else {
                prin(output, total) << std::endl;
                total = trans;
            }
        }
            //这里的打印不再打印在屏幕上,而是直接输出到与putput关联的文件中。
        prin(output, total) << std::endl;
    }
    else {
        std::cerr << "No data?!" << std::endl;
    }
      return 0;
}
题:8_09
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
//接受并打印istringstream的内容
istream &fun8_09(istringstream &c)
{
     string st;
     c>>st;
     cout<<st<<endl;
     c.clear();
     return c;
}
int main( int argc, char **argv)
{
     istringstream ms( "hallo 2018" );
     fun8_09(ms); //结果输出hallo,所以string流可以应用在一行中挨个输出单词。
      return 0;
}
题:8_10
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
//从文件读一行,然后用vector保存
void fun8_10( const string &fName, vector<string> &sec1)
{
     string line;
     ifstream f1(fName);
      if (f1)
     {
            while (getline(f1,line))
                sec1.push_back(line);
     }
}
int main( int argc, char **argv)
{
     vector<string> sec;
     fun8_10( "D:/abc.txt" , sec);
     
      //用istringstram流 读取行中内容,然后输出
      for ( auto it=sec.begin(); it!=sec.end(); ++it)
     {
           istringstream s(*it);
           string word;
            while (s>>word)
                cout<< "  " << word<<endl;
     }
      return 0;
}
题:8_11
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
class personInfo
{
public :
     string name;
     vector<string> phones;
};
int main( int argc, char **argv)
{
     ifstream f1( "D:/cba.txt" );
     vector<personInfo> p1;
     string line;
      if (f1)
     {
           istringstream record;
           record.clear();
            while (getline(f1,line))
           {
                personInfo Info;
                string word;
                record.str(line);
                record>>Info.name;
                 while (record>>word)
                     Info.phones.push_back(word);
                p1.push_back(Info);
                record.clear();
           }
     }
      for ( auto it=p1.begin(); it!=p1.end(); ++it)
     {
           cout<<endl<<it->name<< " :" <<endl;
            for ( auto p1 = it->phones.begin(); p1!=it->phones.end(); ++p1)
                cout<<(*p1)<<endl;
     }
      return 0;
}
题:8_13 (因为8_11 是从文件读取,所以这里只需修改上一题的输出,输出到文件即可)
     ofstream f2( "D:/aaa.txt" );
      for ( auto it=p1.begin(); it!=p1.end(); ++it)
     {
           f2<<endl<<it->name<< " :" <<endl;
            for ( auto p1 = it->phones.begin(); p1!=it->phones.end(); ++p1)
                f2<<(*p1)<<endl;
     }
      return 0;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值