C++ IO

IO类

C++标准库中一共有三种IO类,输入输出(iostream),文件输入输出(fstream),字符串输入输出(sstream),具体类型如下,其中以w开头的类型是宽字符版本,sstream和fstream继承自iostream,所以这些类型之间有着共同的特性。

类型 头文件
istream,wistream从流读取数据 iostream
ostream,wostream向流写入数据 iostream
iostream,wiostream读写流 iostream
ifstream,wifstream从文件读取数据 fstream
ofstream,wofstream向文件写入数据 fstream
fstream,wfstream读写文件 fstream
istringstream,wistringstream从string读取数据 sstream
ostringstream,wostringstream向string写入数据 sstream
stringstream,wstringstream读写string sstream

常见IO对象

  • cin,一个istream对象,从标准输入读取数据。
  • cout,一个ostream对象,从标准输出写入数据。
  • cerr,一个ostream对象,用于输出错误消息。
  • getline函数,从一个给定的输入流读取一行数据存入string对象。

IO对象无拷贝或赋值

int main(void)
{
    std::ofstream out1, out2;
    std::ofstream out3 = out1;//错误,无法使用拷贝初始化
    out1 = out2;//错误,无法使用拷贝赋值运算符
    system("pause");
    return 0;

IO对象状态

IO操作有可能发生错误,有些错误是可恢复的,有些错误则不能恢复,下面函数可以帮助我们访问和设置IO对象的状态,其中badbit置位表示发生了系统级错误,无法恢复;failbit置位表示虽然IO操作出现了问题,但是这种问题是可以修正的,流还可以继续使用;如果到达文件结束,则eofbit和failbit都会被置位;如果badbit,failbit,eofbit任意一个被置位了,则检测流状态的条件都会失败。

函数 描述
eof() 若流的eofbit置位,则返回true,表示流到达了文件结束
fail() 若流的failbit或badbit置位,则返回true,表示IO操作失败了
bad() 若流的badbit置位,则返回true,表示发生了系统级错误,无法恢复
good() 若流处于有效状态,则返回true
clear() 将流的所有状态位复位,将流的状态设置为有效
clear(flags) 根据给定的标志位,将流对应的状态位复位
setstate(flags) 根据给定的标志位,将流对应的状态位置位
rdstate() 返回流当前的状态
    static constexpr _Iostate goodbit = (_Iostate)0x0;
    static constexpr _Iostate eofbit = (_Iostate)0x1;
    static constexpr _Iostate failbit = (_Iostate)0x2;
    static constexpr _Iostate badbit = (_Iostate)0x4;

下面代码中,当输入数据不能转换为int时读操作就会失败,cin的failbit就会置位。

int main(void)
{
    int intValue;
    while (true)
    {
        if (std::cin >> intValue) {
            std::cout << "输入正确:" << std::cin.rdstate() << std::endl;
        }else {
            std::cout << "输入错误:"<< std::cin.rdstate() << std::endl;
            break;
        }
    }
    std::cout << "failbit:" << std::ios_base::failbit << std::endl;
    system("pause");
    return 0;
}

1
输入正确:0
b
输入错误:2

管理输出缓冲

每个输出流都管理一个缓冲区,缓冲区的存在可以使多次写操作合并为一次,从而提高性能,只有在缓冲区刷新的时候才真正的写到设备或文件。下列情况下缓冲区被刷新:

  • 程序正常结束时,缓冲区被刷新。
  • 缓冲区满时,缓冲区被刷新。
  • 可以使用操纵符例如endl显式刷新缓冲区。
int main(void)
{
    std::cout << "hello,world"  << std::endl;//输出hello,world和一个换行,然后刷新缓冲区
    std::cout << "hello,world" << std::flush;//输出hello,world,然后刷新缓冲区
    std::cout << "hello,world" << std::ends;//输出hello,world和一个空字符,然后刷新缓冲区
    system("pause");
    return 0;
}
  • 可以使用操纵符unitbuf设置流的内部状态,使任何输出都立即刷新,无缓冲。
int main(void)
{
    std::cout << std::unitbuf;//所有输出操作立即刷新缓冲区
    std::cout << "hello,world";
    std::cout << std::nounitbuf;//回到正常的缓冲方式
    system("pause");
    return 0;
}

  • 当一个输入流被关联到一个输出流的时候,任何试图从输入流读取数据的操作都会先刷新关联的输出流,例如cin和cout。
int main(void)
{
    std::ostream* out1 = std::cin.tie();//获取cin关联的输出流
    *out1 << out1 << std::endl;
    std::cin.tie(out1);//关联cin和cout
    system("pause");
    return 0;
}

你可能感兴趣的:(C++ IO)