@@ -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**。对给定的任务提供合适的容器及其上有用的基本操作,是构建任何程序的重要步骤。
0 commit comments