Skip to content

Commit

Permalink
填补和修改
Browse files Browse the repository at this point in the history
  • Loading branch information
Shujia Huang authored and Shujia Huang committed Feb 8, 2022
1 parent 0e069c3 commit 7a170f7
Showing 1 changed file with 21 additions and 24 deletions.
45 changes: 21 additions & 24 deletions booknotes/chapter06.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,17 @@ C++ 规定 `||` 运算符是个顺序点(sequence point)。也是说,先

## 6.3 字符函数库 `cctype`

C++ 从 C 语言继承了一个与字符相关的、非常方便的函数软件包, 它可以简化诸如确定字符是否为大写字母、数字、标点符号等工作,这 些函数的原型是在头文件`cctype`(老式的风格中为 `ctype.h`)中定义的。 例如,如果 `ch` 是一个字母,则 `isalpha(ch)` 函数返回一个非零值,否则返回 `0`。同样,如果 `ch` 是标点符号(如逗号或句号),函数 `ispunct(ch)` 将返回 `true`。(这些函数的返回类型为 `int`,而不是 `bool`, 但通常 `bool` 转换让您能够将它们视为`bool` 类型
C++ 从 C 语言继承了一个与字符相关的、非常方便的函数软件包, 它可以简化诸如确定字符是否为大写字母、数字、标点符号等工作,这 些函数的原型是在头文件`cctype`(老式的风格中为 `ctype.h`)中定义的。 例如,如果 `ch` 是一个字母,则 `isalpha(ch)` 函数返回一个非零值,否则返回 `0`。同样,如果 `ch` 是标点符号(如逗号或句号),函数 `ispunct(ch)` 将返回 `true`。(**注意这些函数的返回类型为 `int`,而不是 `bool`, 但通常 `bool` 转换能够将它们视为`bool` 类型**

![image-20210728232352198](https://static.fungenomics.com/images/2021/07/image-20210728232352198.png)

`isalpha()` 不仅更容易使用,而且更通用。AND/OR格式假设A-Z的 字符编码是连续的,其他字符的编码不在这个范围内。这种假设对于 ASCII码来说是成立的,但通常并非总是如此
`isalpha()` 不仅更容易使用,而且更通用。例子中用AND/OR格式假设A-Z的字符编码是连续的,其他字符的编码不在这个范围内。这种假设对于ASCII码来说是成立的,但也并非总是如此

具体地说:

- `isalpha()` 用来检查字符是否为字母字符;
- `isdigits()` 用来测试字符是否为数字字符,如 3;
- `isspace()` 用来测试字符是否为空白,如换行符、空格和制表符;
- `isdigit()` 用来测试字符是否为数字字符(0~9),如 3;
- `isspace()` 用来测试字符是否为空白,包括换行符、空格和制表符;
- `ispunct()` 用来测试字符是否为标点符号。

![image-20210728232647223](https://static.fungenomics.com/images/2021/07/image-20210728232647223.png)
Expand All @@ -101,7 +101,7 @@ C++ 从 C 语言继承了一个与字符相关的、非常方便的函数软件

## 6.4 `?:` 运算符

C++有一个常被用来代替 `if else` 语句的运算符,这个运算符被称为条件运算符 `?:`,它是C++中唯一一个需要3个操作数的运算符,也叫 **三目运算符**
C++有一个常被用来代替 `if else` 语句的运算符,这个运算符被称为条件运算符 `?:`,它是C++中唯一一个需要3个操作数的运算符,也叫**三目运算符**

```Cpp
expression1 ? expression2 : expression3
Expand All @@ -114,7 +114,7 @@ expression1 ? expression2 : expression3

![image-20210728234430665](https://static.fungenomics.com/images/2021/07/image-20210728234430665.png)

`switch` 语句与 Pascal 等语言中类似的语句之间存在重大的差别。 C++中的 `case` 标签只是行标签,而不是选项之间的界线。也是说,程序跳到 `switch` 中特定代码行后,将依次执行之后的所有语句,除非有明确 的其他指示。程序不会在执行到下一个 `case` 处自动停止,要让程序执行 完一组特定语句后停止,必须使用`break` 语句。这将导致程序跳到 `switch` 后面的语句处执行。
`switch` 语句与 Pascal 等语言中类似的语句之间存在重大的差别。 C++中的 `case` 标签只是行标签,而不是选项之间的界线。也是说,程序跳到 `switch` 中特定代码行后,将依次执行之后的所有语句,除非有明确的其他指示。程序不会在执行到下一个 `case` 处自动停止,**要让程序执行 完一组特定语句后停止,必须使用`break` 语句**。这将导致程序跳到 `switch` 后面的语句处执行。

![image-20210728234458366](https://static.fungenomics.com/images/2021/07/image-20210728234458366.png)

Expand Down Expand Up @@ -150,21 +150,19 @@ cin >> n;
- `cin` 对象中的一个错误标记被设置;
-`cin` 方法的调用将返回 `false`(如果被转换为 `bool` 类型)。

**方法返回 `false` 意味着可以用非数字输入来结束读取数字的循环**。当用户输入的不是数字时,该程序将不再读取输入。非数字输入设置错误标记意味着必须重置该标记,程序才能继续读取输 入。`clear()` 方法重置错误输入标记,同时也重置文件尾(`EOF`条件,参见第5章)。输入错误和 `EOF` 都将导致`cin`返回 `false`


**方法返回 `false` 意味着可以用非数字输入来结束读取数字的循环**。当用户输入的不是数字时,该程序将不再读取输入。非数字输入设置错误标记意味着**必须重置该标记,程序才能继续读取输 入**`clear()` 方法重置错误输入标记,同时也重置文件尾(`EOF`条件,参见第5章)。输入错误和 `EOF` 都将导致`cin`返回 `false`

![image-20210729001427328](https://static.fungenomics.com/images/2021/07/image-20210729001427328.png)

![image-20210729001350955](https://static.fungenomics.com/images/2021/07/image-20210729001350955.png)

如果用户输入非数字输入,程序将拒绝,并要求用户继续输入数 字。可以看到,可以使用cin输入表达式的值来检测输入是不是数字。 程序发现用户输入了错误内容时,应采取3个步骤:
如果用户输入非数字输入,程序将拒绝,并要求用户继续输入数字。可以看到,可以使用 `cin` 输入表达式的值来检测输入是不是数字。 程序发现用户输入了错误内容时,应采取3个步骤:

- 重置 `cin` 以接受新的输入;
- 删除错误输入;
- 提示用户再输入。

请注意,程序必须先重置cin,然后才能删除错误输入。程序清单 6.14演示了如何完成这些工作。
请注意,程序必须先重置cin,然后才能删除错误输入。如下程序清单 6.14演示了如何完成这些工作。

```Cpp
#include <iostream>
Expand All @@ -177,14 +175,12 @@ int main() {
cout << "Please enter your golf scores.\n";
cout << "You must enter " << Max << " rounds.\n";
int i;
for (i = 0; i < Max; i++)
{
for (i = 0; i < Max; i++) {
cout << "round #" << i+1 << ": ";
while (!(cin >> golf[i])) {
cin.clear(); // reset input
while (cin.get() != '\n')
continue; // get rid of bad input
cout << "Please enter a number: ";
}
}
Expand All @@ -210,13 +206,15 @@ int main() {
## 6.8 简单文件输入/输出

### 6.8.1 文本I/O和文本文件

### 6.8.2 写入到文本文件中

文件输出:

- 必须包含头文件 `fstream`
- 头文件 `fstream` 定义了一个用于处理输出的 `ofstream` 类;
- 需要声明一个或多个ofstream变量(对象),并以自己喜欢的方式 对其进行命名,条件是遵守常用的命名规则;
- 必须指明名称空间 `std`例如,为引用元素 `ofstream`,必须使用编译指令`using` 或前缀 `std::`
- 需要声明一个或多个 `ofstream` 变量(对象),并以自己喜欢的方式 对其进行命名,条件是遵守常用的命名规则;
- 必须指明名称空间 `std`例如,为引用元素 `ofstream`,必须使用编译指令`using` 或前缀 `std::`
- 需要将 `ofstream` 对象与文件关联起来。为此,方法之一是使用 `open()` 方法;
- 使用完文件后,应使用方法 `close()` 将其关闭;
- 可结合使用 `ofstream` 对象和运算符 `<<` 来输出各种类型的数据。
Expand All @@ -225,9 +223,9 @@ int main() {

![image-20210729232741786](https://static.fungenomics.com/images/2021/07/image-20210729232741786.png)

注意,方法open( )接受一个C-风格字符串作为参数,这可以是一个 字面字符串,也可以是存储在数组中的字符串。
注意,方法`open()` 只接受C-风格字符串作为参数,这可以是一个 字面字符串,也可以是存储在数组中的字符串。

重要的是,声明一个ofstream对象并将其同文件关联起来后,便可 以像使用cout那样使用它。所有可用于cout的操作和方法(如<<、endl 和setf( ))都可用于ofstream对象(如前述示例中的outFile和fout)。
重要的是,声明一个`ofstream`对象并将其同文件关联起来后,便可以像使用cout那样使用它。所有可用于cout的操作和方法(如<<、endl 和setf( ))都可用于ofstream对象(如前述示例中的outFile和fout)。

总之,使用文件输出的主要步骤如下:

Expand All @@ -237,8 +235,7 @@ int main() {
- 就像使用 `cout` 那样使用该 `ofstream` 对象;
- 调用 `close()` 成员函数,关闭文件。

> 默认情况下,`open()` 将首先截断该文件,即将其长度截短到零——丢其原有的内容,然后将新 的输出加入到该文件中。
> 默认情况下,`open()` 的将首先截断该文件,即将其长度截短到零——丢弃原有的内容,然后将新的输出加入到该文件中。
### 6.8.3 读取文本文件

Expand All @@ -255,7 +252,7 @@ int main() {
- 可以结合使用 `ifstream``eof()``fail()` 等方法来判断输入是否成功;
- `ifstream` 对象本身被用作测试条件时,如果最后一个读取操作成 功,它将被转换为布尔值 `true`,否则被转换为 `false`

如果试图打开一个不存在的文件用于输入,情况将如何呢?这种错 误将导致后面使用`ifstream` 对象进行输入时失败。检查文件是否被成功打开的首先方法是使用方法`is_open()`,为此,可以使用类似于下面的代码:
如果试图打开一个不存在的文件用于输入,情况将如何呢?这种错误将导致后面使用`ifstream` 对象进行输入时失败。检查文件是否被成功打开的首选方法是使用`is_open()`,为此,可以使用类似于下面的代码:

```Cpp
inFile.open("b.txt");
Expand All @@ -264,7 +261,7 @@ if (!inFile.is_open()) {
}
```

如果文件被成功地打开,方法 `is_open()` 将返回 `true`;因此如果文件没有被打开,表达式 `!inFile.isopen()` 将为 `true`。函数 `exit()` 的原型是在头文件 `cstdlib` 中定义的,在该头文件中,还定义了一个用于同操作系统通信的参数值 `EXIT_FAILURE`。函数 `exit()` 终止程序。
如果文件被成功地打开,方法 `is_open()` 将返回 `true`;因此如果文件没有被打开,表达式 `!inFile.is_open()` 将为 `true`。函数 `exit()` 的原型是在头文件 `cstdlib` 中定义的,在该头文件中,还定义了一个用于同操作系统通信的参数值 `EXIT_FAILURE`。函数 `exit()` 终止程序。

> 方法 `is_open()` 是C++中相对较新的内容。如果读者的编译器不支持它,可使用较老的方法 `good()` 来代替。
Expand All @@ -282,7 +279,7 @@ if (!inFile.is_open()) {

> 检查文件是否被成功打开至关重要。
读取文件时,有 几点需要检查。首先,程序读取文件时不应超过EOF。如果最后一次读 取数据时遇到 `EOF`,方法 `eof()` 将返回 `true`。其次,程序可能遇到类型不 匹配的情况。例如,程序清单6.16期望文件中只包含数字。如果最后一次读取操作中发生了类型不匹配的情况,方法 `fail()` 将返回 `true`(如果遇到了 `EOF`,该方法也将返回 `true`)。最后,可能出现意外的问题,如文 件受损或硬件故障。如果最后一次读取文件时发生了这样的问题,方法 `bad()` 将返回 `true`。不要分别检查这些情况,一种更简单的方法是使用 `good()` 方法,该方法在没有发生任何错误时返回 `true`
读取文件时,有 几点需要检查。首先,程序读取文件时不应超过 EOF。如果最后一次读取数据时遇到 `EOF`,方法 `eof()` 将返回 `true`。其次,程序可能遇到类型不 匹配的情况。例如,程序清单6.16期望文件中只包含数字。如果最后一次读取操作中发生了类型不匹配的情况,方法 `fail()` 将返回 `true`(如果遇到了 `EOF`,该方法也将返回 `true`)。最后,可能出现意外的问题,如文 件受损或硬件故障。如果最后一次读取文件时发生了这样的问题,方法 `bad()` 将返回 `true`。不要分别检查这些情况,一种更简单的方法是使用 `good()` 方法,该方法在没有发生任何错误时返回 `true`

```Cpp
while (inFile.good()) {
Expand Down Expand Up @@ -324,7 +321,7 @@ while (inFile >> value) { // read and test for success

## 6.9 总结

C++提供了 `if` 语句、`if else`语句和 `switch` 语句来管理选项。
C++提供了 `if` 语句、`if-else` 语句和 `switch` 语句来管理选项。
C++还提供了帮助决策的运算符。通过使用逻辑运算符(`&&``||``!`),可以组合或修改关系表达式,创建更细致的测试。条件运算符 `(?:)` 提供了一种选择两个值之一 的简洁方式。

`cctype` 字符函数库提供了一组方便的、功能强大的工具,可用于分析字符输入。
Expand Down

0 comments on commit 7a170f7

Please sign in to comment.