I/O(Input/Output),C++语言不直接处理输入输出,而是通过一族定义在标准库中的类型来处理IO。

这些类型支持从设备读取数据、向设备写入数据的IO操作,设备可以是文件、控制台窗口等。

为了支持不同类型的IO处理操作,C++的IO类型定义在三个独立的头文件中:(w:宽字符)

  • iostream定义了用于读写流的基本类型;
    • istream,wistream从流读取数据
    • ostream, wostream向流写入数据
    • iostream,wiostream读写流
  • fstream定义了读写命名文件的类型;
    • ifstream, wifstream从文件读取数据
    • ofstream, wofstream项文件写入数据
    • fstream,wfstream读写文件
  • sstream定义了读写内存string对象的类型。
    • istringstream,wistringstream从string读取数据
    • ostringstream,wostringstream向string写入数据
    • stringstream,wstringstream读写string

常见IO对象

  • cin,一个istream对象,从标准输入读取数据。

  • cout,一个ostream对象,从标准输出写入数据。

  • cerr,一个ostream对象,用于输出错误消息。

  • getline函数,从一个给定的输入流读取一行数据存入string对象。

1. 使用cout进行输出

<<运算符的默认含义是按位左移运算符,ostream类将<<重载为输出,在这种情况下,<<被称为插入运算符,能都识别C++中所有的基本类型

1
2
cout << 88;
ostream & operator<<(int);
  • 输出与指针

    ostream类为下面的指针类型定义了插入运算符函数:

    • const signed char *;
    • const unsigned char *;
    • const char *;
    • void *;
    1
    2
    3
    4
    5
    int eggs = 12;
    char *amount = "dozen";
    cout << &eggs << endl;
    cout << amount << endl;
    cout << (void *)amount << endl; //字符串的地址
  • 拼接输出

    插入运算符的返回类型都是ostream &。

    因此:cout<<a<<b<<endl;

  • 其他ostream方法

    ostream类还提供了put()write()方法,前者用于显示字符,后者用于显示字符串

    1
    2
    cout.put('W').put(65).put('\n'); //显示字符:WA
    cout.write("Hezil", 3); //显示字符串:Hez
  • endl, ends, flush;

    1
    2
    cout << "hello" << ends << "world" <<endl;
    cout << "hello" << flush << "world" <<endl;

2. 使用cin进行输入

1
istream & operator>>(int &);

istream类还为下列字符指针类型重载了>>抽取运算符;

  • signed char *;
  • char *;
  • unsigned char *;
1
2
3
4
int val;
while(cin>>val) //判断输入是否为int类型
{
}
  • 流状态

    cin或者cout包含一个描述流状态(stream state)的数据成员(从ios_base类继承而来),由三个ios_base元素组成:eofbitbadbitfailbit

    • eofbit

      如果到达文件尾,则设置为1

    • badbit

      如果流被破坏,则设置为1,例如:文件读取错误

    • failbit

      如果输入操作未能读取预期的字符或输出操作没有写入预期的字符,则设置为1;

    设置流状态:

    • ```c++
      clear(); //清楚全部三个状态位
      clear(eofbit);
      setstate(eofbit);
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26

      - 流状态的影响:

      设置流状态有一个非常重要的后果,流将对后面的**输入或输出**关闭,直到位被清除;

      ```c++
      int input;
      int sum = 0;
      cout << "输入数字:\n";
      while (cin >> input)
      {
      sum += input;
      cout << input << ends;
      }
      if (cin.eof() || cin.bad() || cin.fail())
      {
      cout << "循环关闭,\n";
      }
      cout << "??????";
      cout << "最后数字为:" << input << ",sum=" << sum << endl;
      cout << "再次输入数字:\n";
      cin.clear(); //状态流重置
      while (!isspace(cin.get())) //处理之前导致输入终止的不匹配输入
      continue;
      cin >> input; //输入失效
      cout << input << endl;
  • 其他istream方法

    • 单字符输入

      • get(char &),返回类型为istream &, 到达文件尾的返回值转化为false
      1
      2
      3
      4
      5
      6
      7
      8
      char ch,ch1;
      cin.get(ch).get(ch1);

      char ch;
      while(cin.get(ch))
      {
      //process input;
      }
      • get(void),返回类型为int
      1
      2
      3
      4
      5
      6
      7
      8
      char ch;	//or char ch
      ch = cin.get();

      int ch;
      while((ch=cin.get())!=EOF)
      {
      //process
      }
    • 字符串输入

      1
      2
      3
      4
      5
      istream & get(char *, int, char);
      istream & get(char *, int);

      istream & getline(char *, int, char);
      istream & getline(char *, int);

      第一个参数适用于放置输入字符串的内存单元地址,第二个参数比要读取的最大字符数大一(额外的一个字符用于存储结尾的空字符串),第三个参数指定用作分界符的字符,只有两个参数的版本将换行符作为默认分界符。

      • getline()
      • get()
      • ignore()
      1
      istream & ignore(int =1, int = EOF);

      ​ 默认参数EOF导致ignore()读取指定数目的字符或读取到文件未。

3. 文件输入和输出

  • 写入文件流程

    1. 创建一个ofstream对象来管理输出流;
    2. 将该对象与特定的文件关联起来;
    3. 以使用cout的方式使用该对象,唯一的区别是输出将进文件而不是屏幕;
    1
    2
    3
    4
    5
    6
    ofstream fout;
    fout.open("jar.txt");

    ofstream fout("jar.txt");

    fout.close()
  • 读取文件流程

    1. 创建一个ifstream对象来管理输入流;
    2. 将对象与特定的文件关联;
    3. 以使用cin的方式使用该对象;
    1
    2
    3
    4
    5
    6
    ifstream fin;
    fin.open("jar.txt");

    ifstream fin("jar.txt");

    fin.close();
  • 检查文件是否被打开:

    if (fin.is_open())

  • 文件模式

    文件模式描述的是文件将被如何使用:读、写、追加等。

    1
    2
    3
    ifstream fin("filename", mode);

    ofstream fout("filename", mode);

    文件模式常量

    • ios_base::in:打开文件,以便读取。
    • ios_base::out:打开文件,以便写入
    • os_base::ate:打开文件,并移到文件尾
    • ios_base::app:追加到文件尾
    • ios_base::binary:二进制文件
    • ios_base::trunc:如果文件存在,则截短文件(以前的内容将被删除);
    1
    2
    ofstream fout("jas.txt", ios_base::out | ios_base::app);
    //合并模式,启用out和app模式

暂时写到这里,其实这里的知识很多很复杂…