# 一、概述
C++ 中的流(streams)是用于处理输入和输出的抽象概念,主要用于与设备(如键盘、屏幕、文件等)进行数据交互。流在 C++ 中主要由以下几个方面组成:
# 1. 流的类型
C++ 中有两种主要的流类型:
输入流(Input Stream):用于从输入设备读取数据。最常用的输入流是
std::cin
,它用于从标准输入(通常是键盘)读取数据。输出流(Output Stream):用于将数据输出到输出设备。最常用的输出流是
std::cout
,它用于将数据输出到标准输出(通常是屏幕)。
# 2. 流的类
在 C++ 中,流是通过类来实现的,主要有以下几个类:
std::istream
:用于输入流的基类,提供了基本的输入操作。std::ostream
:用于输出流的基类,提供了基本的输出操作。std::fstream
:用于文件的输入输出操作,既可以读取文件也可以写入文件。
# 3. 基本操作
输入操作:
使用std::cin
读取数据可以用>>
操作符。例如:1
2
3int x;
std::cout << "请输入一个整数:";
std::cin >> x;输出操作:
使用std::cout
输出数据可以用<<
操作符。例如:1
std::cout << "你输入的整数是:" << x << std::endl;
# 4. 文件流
对于文件的读写,使用 std::ifstream
和 std::ofstream
类:
读取文件:
1
2
3
4
5
6
7std::ifstream infile("data.txt");
if(infile.is_open()) {
int value;
while(infile >> value) {
std::cout << value << std::endl;
} infile.close();
}写入文件:
1
2
3
4
5std::ofstream outfile("output.txt");
if(outfile.is_open()) {
outfile << "Hello, World!" << std::endl;
outfile.close();
}
# 5. 流的格式化
C++ 的流可以进行格式化操作,例如控制输出的精度、宽度等:
设置精度:
1
2std::cout.precision(2); // 设置小数精度为2
std::cout << std::fixed << 3.14159 << std::endl; // 输出为3.14设置宽度:
1
std::cout << std::setw(10) << std::setfill('0') << x << std::endl; // 设置输出宽度为10,使用0填充
更多细节,见下文:输入输出操纵符
# 6. 错误处理
流还提供了错误处理的功能,可以通过检查流的状态来确定操作是否成功:
1 | if(std::cin.fail()) { |
# 7. 流的优先级
C++ 中的流操作优先级比较高,可以方便地进行链式操作。例如:
1 | std::cout << "请输入一个数字:" << std::endl; |
在 C++ 中,流的优先级指的是可以将多个流操作(输入或输出)串联在一起进行的能力。这种方式使得代码更加简洁和易读。
# 二、字符串流
# 1. 什么是 std::stringstream
std::stringstream
是 C++ 标准库中的一个类,位于 <sstream>
头文件中。它允许程序员在内存中创建一个字符串流,支持输入和输出操作。简单来说, std::stringstream
结合了 std::istringstream
和 std::ostringstream
的功能,既可以从字符串中读取数据,也可以向字符串中写入数据。
# 2. 基本特性
- 输入输出:可以使用
>>
和<<
操作符进行输入和输出操作。 - 字符串存储:可以在内存中动态创建和操作字符串。
- 格式化能力:可以像其他流一样对数据进行格式化。
# 3. 主要方法
构造函数:
1
2std::stringstream ss; // 默认构造函数
std::stringstream ss("初始字符串"); // 使用字符串初始化写入数据:
使用<<
操作符将数据写入流:1
ss << "Hello, " << 42 << "!";
读取数据:
使用>>
操作符从流中读取数据:1
2
3std::string str;
int num;
ss >> str >> num; // 根据空格分隔读取获取字符串:
使用.str()
方法获取流中的完整字符串:1
std::string result = ss.str();
清空流:
可以使用.clear()
方法清空流的状态,并用.str("")
清空内容:1
2ss.str(""); // 清空字符串内容
ss.clear(); // 清空流状态
注意! 当我们要清空 stringstream 时,不应该调用 clear()
,而是调用 str("")
。
1 |
|
clear 只是清空流的状态,并不是清空其内容。
# 4. 应用场景
- 格式化输出:当需要将多个数据格式化为一个字符串时,
std::stringstream
非常有用。 - 数据解析:从格式化的字符串中提取数据,特别适合处理 CSV、JSON 等格式。
- 临时存储:在不想直接创建临时字符串的情况下,可以使用
std::stringstream
进行中间处理。
# 5. 性能
由于 std::stringstream
在内存中操作字符串,性能通常比频繁的字符串拼接更高效,尤其是在处理大量数据时。
# 三、其他
# i、Input/output manipulators
在 C++ 中,输入 / 输出操纵符(Input/Output Manipulators)是用于格式化输入和输出的特殊函数。它们可以被应用于流操作,以改变输出的格式、对齐方式、小数位数等。通过使用这些操纵符,你可以更精确地控制输出的外观,使得代码更易于阅读和维护。
以下是一些常用的输入 / 输出操纵符:
std::setw(int n)
:
设置字段宽度。
用于指定下一个输出项的字段宽度为 n
个字符,如果输出的项长度不足 n
,则会使用空格填充。
1 |
|
std::setfill(char c)
:
设置填充字符。
用于指定填充字符,该字符会被用来填充字段宽度之外的空白位置。
1 |
|
这个函数可用于 0 的填充,如 16 进制的前置零:0x0A、0x03
std::setprecision(int n)
:
设置小数位数。
用于控制浮点数的输出精度,指定小数点后的位数为 n
。
1 |
|
std::fixed
和 std::scientific
:
设置浮点数输出格式为固定小数点和科学计数法。
可以与 std::setprecision
一起使用,后者用于控制精度。
1 |
|
std::hex
、 std::oct
和 std::dec
:
用于设置整数的输出进制,分别为十六进制、八进制和十进制。
1 |
|
另外,还有一些实用的操纵符:
1 | # 将布尔值用 true 和 false 打印 |
# i、cin.ignore()
ignore()
是 istream 类的成员函数,它的原型是:
1 | istream & ignore(int n = 1, int delim = EOF); |
此函数的作用是跳过输入流中的 n 个字符,或跳过字符 delim 及其之前的所有字符 —— 哪个条件先满足就按哪个执行。两个参数都有默认值,因此 cin.ignore()
就等效于 cin.ignore(1, EOF)
, 即跳过一个字符。
1 |
|
通过该函数,能够过滤掉一些冗余信息,便于提取我们想要的信息。