Skip to content

Commit 02d0419

Browse files
committed
Update public notes
1 parent b692e79 commit 02d0419

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

content/编程相关/编程语言/Cpp 之旅 第三版 读书笔记.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,165 @@ regex_token_iterator:遍历未匹配部分
11291129
11301130
#todo 第11章 输入和输出
11311131
1132+
## 第11章 输入和输出
1133+
1134+
> I/O 流库提供了文本和数值的输入输出功能,这种格式化和非格式化的输入都带有缓冲。它提供了类型安全,同时也可以扩展为像支持内置类型一样支持用户自定义类型。
1135+
>
1136+
> 文件系统库提供了操作文件和目录的基本工具。
1137+
1138+
标准库流可以用于二进制 IO、用于不同字符类型、用于不同区域设置,也可以用高级缓冲策略。 *但是这本书不讲,超出讨论范围了。*
1139+
1140+
流可以往标准库 string 输入和输出数据,或者往 string 缓冲区写格式化的数据,或者往内存区域写,或者往文件 IO 写。
1141+
1142+
输入和输出都有析构函数,可以释放拥有的资源(比如缓冲区和文件句柄)。也是 RAII 的示例。
1143+
1144+
### 输出
1145+
1146+
`<ostream>`
1147+
1148+
cout 是标准输出流,cerr 是报告错误的标准流。通常写入 cout 的值被转换成字符序列。
1149+
1150+
输出表达式的结果是输出流的引用,所以可以用来继续输出,也就是:
1151+
1152+
```cpp
1153+
cout << "the value of i is" << i << "\n";
1154+
```
1155+
1156+
注意,输出一个字符的结果就是其字符形式,而不是数值:
1157+
1158+
```cpp
1159+
int b = 'b'; // char 隐式转 int
1160+
char c = 'c';
1161+
cout << 'a' << b << c; // a98c
1162+
```
1163+
1164+
### 输入
1165+
1166+
`<istream>`
1167+
1168+
*感觉 cin cout 只是包装了 scanf 和 printf. 能够少写格式化字符串而已.*
1169+
1170+
可以用 `getline()` 来获取一整行。
1171+
1172+
> 使用格式化 IO 操作不那么容易出错,而且更有效率。特别地,istream 会处理好内存管理和范围检查。可以从字符串流和内存流写入或读出格式化的内容。
1173+
1174+
### I/O 状态
1175+
1176+
每个 iostream 都有状态,可以通过这个状态来判断流操作是否成功。
1177+
1178+
比如说读取序列:
1179+
1180+
```cpp
1181+
vector<int> read_ints(istream& is) {
1182+
vector<int> res;
1183+
for (int i; is>>i;) {
1184+
res.push_back(i);
1185+
return res;
1186+
}
1187+
}
1188+
```
1189+
1190+
is >> i 返回是 istream 引用, iostream 对象流结果为 true 的话,表示流已经准备好进行下一个操作。
1191+
1192+
iostream状态 包含了读写所需要的所有信息。比如说格式化信息、错误状态、缓冲。此外,也可以认为设置状态来表示错误,或者人为清除状态。 `iostream.setstate()` `iostream.clear()`.
1193+
1194+
### 用户自定类型的 I/O
1195+
1196+
就重载 << 和 >> 就可以了
1197+
### 输出格式化
1198+
1199+
iostream 和 format 都能控制输入输出的格式。iostream 和 C++ 历史一样悠久,风格是格式化算术数字组成的流。format 是 C++ 20 的新库,风格则是 printf() 规格来格式化。
1200+
1201+
#### 流格式化
1202+
1203+
流的格式化可以用 **格式控制符**。
1204+
1205+
```cpp
1206+
cout << 1234 << ' ' << hex << 1234 << ' ' << oct << 1234 << dec << 1234 << '\n';
1207+
// 1234 4d2 2322 1234
1208+
```
1209+
1210+
也可以设置浮点格式比如说 `scientific` `hexfloat` `fixed` `defaultfloat`.
1211+
1212+
`cout.precision(n)` 设置精度,在输出时会小数会进行四舍五入。
1213+
1214+
浮点格式控制符都是「黏性的」,也就是会在后续浮点值输出中都有效。
1215+
1216+
#### printf() 格式化
1217+
1218+
c语言的 printf 缺乏类型安全。在 `<format>` 中,提供了类型安全的 printf.
1219+
1220+
```cpp
1221+
string s = format("Hello, {}\n", val);
1222+
```
1223+
1224+
**格式化字符串** 后续 `{}` 和参数会决定如何格式化字符串。
1225+
1226+
```cpp
1227+
cout << format("{} {:x} {:o} {:d} {:b}\n", 1234,1234,1234,1234,1234,1234);
1228+
```
1229+
1230+
这样可以指定格式。 *x 代表整数*.
1231+
1232+
```cpp
1233+
cout << format("{3:} {1:x} {2:o} {0:b}\n", 000, 111, 222, 333);
1234+
```
1235+
1236+
冒号前面的数字则指定了使用的参数顺序。(也提供了可以多次使用同一参数的可能)
1237+
1238+
format 浮点数格式化和流的浮点数格式化差不多:
1239+
1240+
- e 科学记数法
1241+
- a 十六进制
1242+
- f 定点
1243+
- g 默认 *这什么鬼缩写,global 吗*
1244+
1245+
format() 提供了一种迷你语言,大约有 60 种格式化描述符。
1246+
1247+
vformat() 接受变量作为格式,更加灵活,也更容易报错。
1248+
1249+
*到最后我还是没看懂类型安全在哪里,仅仅是把 format 拆成了 format 和 vformat,该报错 vformat 还是报错,对自定类型也不友好。*
1250+
1251+
###
1252+
1253+
标准库直接支持下面的流:
1254+
- 标准流
1255+
- 文件流
1256+
- 字符串流
1257+
- 内存流
1258+
- 同步流:*在多线程使用时避免数据竞争的流*
1259+
1260+
也可以自己定义流,比如说通信通道的流。
1261+
1262+
**流不可以被拷贝,只能用引用传递.**
1263+
1264+
标准库流都是模板,参数是字符类型,也就是 `using ostream = basic_ostream<char>`. 支持 unicode 的宽字符流是 `basic_ostream<wchar_t>`.
1265+
1266+
#### 标准流
1267+
1268+
- cout 普通输出
1269+
- cerr 无缓冲错误输出
1270+
- clog 有缓冲日志输出
1271+
- cin 标准输入
1272+
1273+
#### 文件流
1274+
1275+
`<fstream>`.
1276+
1277+
- ifstream 从文件读取数据
1278+
- ofstream 向文件写入数据
1279+
- fstream 用于读写
1280+
1281+
```cpp
1282+
ofstream ofs {"target"};
1283+
if (!ofs)
1284+
error("couldnt open 'source' for reading");
1285+
```
1286+
1287+
#### 字符串流
1288+
1289+
#todo
1290+
11321291
## 第12章 容器
11331292
11341293
> 大多数计算任务都会涉及创建值的集合,然后对这些集合进行操作。一个简单的例子是读取字符并存入 string 中,然后打印这个 string。如果一个类的主要目的是保存对象,那么我们通常称之为 **容器container**。对给定的任务提供合适的容器及其上有用的基本操作,是构建任何程序的重要步骤。
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
created: 2025-11-10
3+
updated: 2025-11-10
4+
---
5+
#todo

0 commit comments

Comments
 (0)