C++IO流-标准输入与输出

  • Post author:
  • Post category:其他



一、I/O类关系

在C++不直接处理输入输出,而是通过标准库中的I/O流类来进行处理。标准库主要有下面一些类:istream,ostream,iostream,ifstream,ofstream,fstream等等。其类关系图如下:

这里写图片描述

其中istream用来处理输入流,ostream处理输出流,iostream处理输入输出流,ifstream处理文件数据输入,ofstream处理文件数据输出,fstream处理文件数据输入输出。sstream中各类主要处理读写内存中string对象。

常见的流处理对象及运算符:

  1. cin 一个istream对象,从标准输入读取数据
  2. cout 一个ostream对象,向标准输出写入数据
  3. cerr 一个ostream对象,用于输出程序错误信息,写入到标准错误
  4. >>运算符,从一个istrem对象读取输入数据
  5. <<运算符,向一个ostream对象写入输出数据

参考

C++标准I/O库用法


二、ifstream,ofstream,fstream

ifstream,ofstream,fstream这3个类都在

<fstream>

中,因此需要用到相关文件处理需要包含此头文件。fstream基本包含了前面两个的功能,下面介绍fstream的用法。创建fstream类对象的方式:

  • fstream obj;创建一个未绑定的文件流
  • fstream obj(“file name”);创建一个文件流,并打开文件名对应的文件
  • fstream obj(“file name”,mode );与2类似,以mode模式打开

第一种方式关联文件需要利用函数open(“file name”,mode ),需要注意的是不管用哪种方式创建文件对象,若是路径下文件不存在想要自动创建相应的文件,则必须加上模式ios::out。打开模式有以下一些方式:

  • ios::in 以读取方式打开文件
  • ios::out 以写入方式打开文件
  • ios::ate 存取指针在文件末尾
  • ios::app 写入时采用追加方式
  • ios::trunc 写入时抹去旧数据
  • ios::binary 以二进制方式存取

对于ifstream默认模式为ios::in,ofstream默认为ios::out,fstream默认为ios::in | ios::out。注意以非app模式打开文件则指针是指向文本首部的,显示使用ios::out打开文件(只有单个out模式,不包含fstream的默认情形),文件内容会被丢弃,阻止清空原数据的方法是使用app模式。

//o=流对象创建
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
    fstream fp;
    fstream fp1("test1.txt");
    fp.open("test.txt", ios::out | ios::app );
    if(!fp)
        cout << "open the file erro-fp" << endl;
    fp << "hello";
    fp.close();
    char *str = new char[10];
    if(!fp1)
        cout << "open the file erro-fp1" << endl;
    fp1>>str;   //从文件输出
    cout << str;
    fp1.close();
}


文件的读写


文件流进行文件的读写可以和cin,cout类似的方式进行,即利用重载的运算符<< ,>>进行文件的输出和读取。也可以用函数get(),getline(),read(),write()等。

具体应用参考:

http://blog.csdn.net/jackyxwr/article/details/4870632


二、标准输入输出流


cin是C++编程语言中的标准输入流对象,即istream类的对象。cin主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。此外,cout是流的对象,即ostream类的对象,cerr是标准错误输出流的对象,也是ostream 类的对象。这里的标准输出指的是终端键盘,标准错误输出指的是终端的屏幕。

cout语句的一般格式为:

cout<<表达式1<<表达式2<<……<<表达式n;

cin语句的一般格式为:

cin>>变量1>>变量2>>……>>变量n;

在定义流对象时,系统会在内存中开辟一段缓冲区,用来暂存输入输出流的数据。在执行cout语句时,先把插入的数据顺序存放在输出缓冲区中,直到输出缓冲区满或遇到cout语句中的endl(或’\n’,ends,flush)为止,此时将缓冲区中已有的数据一起输出,并清空缓冲区。输出流中的数据在系统默认的设备(一般为显示器)输出。cout通过使用头文件iomanip中定义的函数可以实现输出格式控制,常见的函数有:

setprecision(n) 设置实数的精度为n位

setw(n) 设置字段宽度为n位

setfill(c) 设置填充宇符c

setiosflags() 设置输出格式状态,括号中应给出格式状态,内容与控制符setiosflags括号中的内容相同

resetioflags() 终止已设置的输出格式状态,在括号中应指定内容

格式控制状态参考

C++格式化输出,C++输出格式控制

cin相对于cout使用更为复杂,下面分别介绍各用法。

1、cin>>的用法

例:cin>>a>>b; //输入两个值a,b

cin可以连续从键盘读取想要的数据,以空格、tab或换行作为分隔符,当cin>>从缓冲区中读取数据时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin>>会将其忽略并清除,继续读取下一个字符,若缓冲区为空,则继续等待。但是如果读取成功,字符后面的分隔符是残留在缓冲区的,cin>>不做处理。 例中a,b可以是数字,可以是字符,cin根据其数据类型分配缓冲区空间。

2、cin.get()

可以读取一个字符,也可以读取多个字符:

例:ch=cin.get(); //或者cin.get(ch);读取一个字符ch

cin.get(char*s int m); // 从缓冲区读取m个字符到s中

cin.get()从输入缓冲区读取单个字符时不忽略分隔符,直接将其读取,,读取一行时,遇到换行符时结束读取,但是不对换行符进行处理,换行符仍然残留在输入缓冲区,cin>>也是这样,因此用了cin>>之后再用getline之前最好使用syns()清空缓冲区,否则getline()会首先读到一个空字符串。

3、cin.getline()

读取一行字符,与cin.get(cha*s int m)相同,区别在于cin.getline不会将结束符或者换行符残留在输入缓冲区中,即使输入的字符大于m,s的最后一个字符也是换行符’\n’,多出的字符将放在缓冲区,但此时cin的输入标志将关闭,只有经过clear()才能使cin能够继续读数据。

cin.getline(a,4);  //a为数组名或指针,须提前分配空间
cout << a <<endl;
cin.clear();
cin.getline(b,6);
//当第一次cin输入的字符大于4时,必须调用clear(),否则b无法输入,程序将直接退出

4、getline() // 接受一个字符串,可以接收空格并输出

#include<string>   //包含头文件
string s;
getline(cin,s);
getline(cin,s,';');以字符';'为界读取一行数据,';'可以为任意字符
//getline读取一行字符时,默认遇到’\n’时终止,并且将’\n’直接从输入缓冲区中删除掉,
//不会影响下面的输入处理

5、gets()

gets是C中的库函数,在< stdio.h>申明,从标准输入设备读字符串,可以无限读取,不会判断上限,以回车结束或者EOF时停止读取,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。

char s[5];  
gets(s);
//不要char*p,然后gets(p),这是错误的,因为p没有指向有效的内存,
//它可能指向任何非法地址,除非为p分配空间

6、getchar()

从stdio流中读字符,相当于getc(stdin),它从标准输入里读取下一个字符。返回类型为int型,出错返回-1。

int c;

c = getchar();

参考:

C++中cin的详细用法


7、清空输入缓冲区问题

一共有3个函数:clear(),ignore(),sync()

其中clear一般在输入出错时重新设置cin的状态,ingore()清除缓冲区字符,默认清除一个,cin.sync()的作用是清除输入缓冲区全部的内容(让流与其对应的数据源同步,这样流就可以丢弃掉之前没有处理的数据)。

参考:

cin的用法及清空输入缓冲区问题



版权声明:本文为ahafg原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。