C++ IO流

C++ IO流

1、流和缓冲区

流是一个类的对象 ,I/O流提供了一种统一、灵活且类型安全的方式来进行数据的读写。我们可以把流看作是一种数据的载体,通过它可以实现数据交换和传输。

缓存区 是一块用于临时存储数据内存区域。当缓冲区满足特定条件时,数据才会被实际写入或读取。

2、C++标准IO流

C++ 实现了一个庞大的类库,其中 ios 为基类,其他类都是ios 的直接或间接派生。我们常用的 iostream 是由 istream 和 ostream 继承来的,cin 继承于 istream,cout、cerr、clog 继承于 ostream 。c 表示 character,且 cout 只能用于转换为窄字符(narrow characters)流,对于宽字符(wild character)要使用 wout (如果遇到编码问题需要考虑 wout )。

宽、窄两种字符代表两种表示方式,窄字符一般采用单字节编码,用 char 数据类型。宽字符使用多个字节来表示一个字符,使用 wchar_t 数据类型。

C++ 复制代码
int main() {
    char ch = 'A';
    std::cout << "The character is: " << ch << std::endl;
    return 0;
}
C++ 复制代码
int main() {
    wchar_t wch = L'中';
    std::wcout.imbue(std::locale(""));
    std::wcout << L"The wide character is: " << wch << std::endl;
    return 0;
}

L 前缀用于指示这是一个宽字符常量

如果使用char代替wchar_t

C++ 复制代码
int main() {
    char ch = '中';
    std::cout << "The character is: " << ch << std::endl;
    return 0;
}

2.1 标准I/O流对象

C++提供了四个预定义的标准I/O流对象:

  • std::cin:标准输入流,通常与键盘关联,用于从键盘读取数据。
  • std::cout:标准输出流,通常与屏幕关联,用于向屏幕输出数据。
  • std::cerr:标准错误流,通常与屏幕关联,用于输出错误信息,不使用缓冲区,数据会立即输出。
  • std::clog:标准日志流,通常与屏幕关联,用于输出日志信息,使用缓冲区。

值得注意的是,只有cerr是无缓冲,数据会立即被输出到标准错误设备,其他三种均需要等待缓冲区满或是遇到特定条件从缓冲区读入或输出。
clog(标准日志流)还需要配置clog的输出行为。六个日志级别。

2.2 operator bool

cin中的 operator bool() 用于判断流的输入是否正确,operator bool() 有四个流标志位

第一个的正常情况,只有 good()true

第二个是文件结尾错误,如读文件失败,只有 eof()true

第三个是逻辑错误,只有fail()true。发生逻辑错误并不会导致程序结束。

第四个是严重错误,fail()bad() 都是 true。严重错误指发生了程序必须终止的错误。

除非发生严重错误,cin出错之后可以使用 cin.clear()将标记位重置。

2.3 C++文件流

C++ 中 **fstream**标准库,它定义了三个新的数据类型:

数据类型 描述
ofstream 该数据类型表示输出文件流,用于创建文件并向文件写入信息。
ifstream 该数据类型表示输入文件流,用于从文件读取信息。
fstream 该数据类型通常表示文件流,且同时具有 ofstream 和 ifstream 两种功能,这意味着它可以创建文件,向文件写入信息,从文件读取信息。

打开文件

在从文件读取信息或者向文件写入信息之前,必须先打开文件。ofstreamfstream 对象都可以用来打开文件进行写操作,如果只需要打开文件进行读操作,则使用 ifstream 对象。

下面是 open() 函数的标准语法,open() 函数是 fstream、ifstream 和 ofstream 对象的一个成员。

C++ 复制代码
void open(const char *filename, ios::openmode mode);

open() 成员函数的第一参数指定要打开的文件的名称和位置,第二个参数定义文件被打开的模式。

模式标志 描述
ios::app 追加模式。所有写入都追加到文件末尾。
ios::ate 文件打开后定位到文件末尾。
ios::in 打开文件用于读取。
ios::out 打开文件用于写入。
ios::trunc 如果该文件已经存在,其内容将在打开文件之前被截断,即把文件长度设为 0。

我们也可以把两种或两种以上的模式结合使用。

关闭文件

当 C++ 程序终止时,它会自动关闭刷新所有流,释放所有分配的内存,并关闭所有打开的文件。

文件位置指针

istreamostream 都提供了用于重新定位文件位置指针的成员函数。文件位置指针是一个整数值,指定了从文件的起始位置到指针所在位置的字节数。

C++ 复制代码
// 定位到 fileObject 的第 n 个字节(假设是 ios::beg)
fileObject.seekg( n );

// 把文件的读指针从 fileObject 当前位置向后移 n 个字节
fileObject.seekg( n, ios::cur );

// 把文件的读指针从 fileObject 末尾往回移 n 个字节
fileObject.seekg( n, ios::end );

// 定位到 fileObject 的末尾
fileObject.seekg( 0, ios::end );

3. stringstream

cpp 复制代码
#include <sstream>

stringstreamstring 类型变为类似 cin 的字符串流,以空格作为分隔符,将 stringstream 的内容存入其他 string 变量当中。在网络通信的反序列化中有应用。

4. 其他

使用以下三行代码可以加快 IO 流速度,在竞赛中有应用。

cpp 复制代码
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);

原理:

  1. 第一行代码:coutprintf() 都有自己的缓冲区,C++ 兼容 C 语言必须考虑 coutprintf() 的先后顺序不能出错。这行代码将 C++ 的同步保护取消,来提升 IO 速度。
  2. 第二、三行代码:cincerr都与 cout 进行了绑定, tie() 函数就是用于控制绑定的,将其置为空就是对其进行了解绑。
    CSDN文章与作者同名
相关推荐
Starry_hello world1 小时前
C++ 快速幂算法
c++·算法·有问必答
2301_807611494 小时前
77. 组合
c++·算法·leetcode·深度优先·回溯
微网兔子5 小时前
伺服器用什么语言开发呢?做什么用什么?
服务器·c++·后端·游戏
YuforiaCode5 小时前
第十三届蓝桥杯 2022 C/C++组 修剪灌木
c语言·c++·蓝桥杯
YOULANSHENGMENG5 小时前
linux 下python 调用c++的动态库的方法
c++·python
CodeWithMe5 小时前
【C++】STL之deque
开发语言·c++
炯哈哈6 小时前
【上位机——MFC】运行时类信息机制
开发语言·c++·mfc·上位机
rigidwill6667 小时前
LeetCode hot 100—最长有效括号
数据结构·c++·算法·leetcode·职场和发展
阳光_你好8 小时前
C++/Qt中QActionGroup类用法
c++·qt
菜鸟射手8 小时前
QT creater和vs2017文件路径问题
linux·c++·windows·qt