Skip to content

Commit 42ffda4

Browse files
committed
2026spring_middle_lab
1 parent 4a8a509 commit 42ffda4

15 files changed

Lines changed: 596 additions & 51 deletions

File tree

.vitepress/config.mts

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ export default defineConfig({
1414
},
1515
{
1616
text: '大作业文档',
17-
// link: 'https://pku-software.github.io/project-doc/'
18-
link: ''
17+
link: 'https://pku-software.github.io/project-doc/'
1918
}
2019
],
2120

@@ -32,33 +31,33 @@ export default defineConfig({
3231
text: '如何找到问题的答案',
3332
link: '/26spring/before_ask/how_to_find_answers'
3433
},
35-
// {
36-
// text: '写大作业时遇到了问题',
37-
// link: 'https://pku-software.github.io/project-doc/preface/facing-problem.html'
38-
// }
34+
{
35+
text: '写大作业时遇到了问题',
36+
link: 'https://pku-software.github.io/project-doc/preface/facing-problem.html'
37+
}
3938
]
4039
},
4140
{ text: '环境配置', link: 'https://pku-software.github.io/CppEnvSetup/' },
42-
// { text: '中作业',
43-
// items: [
44-
// {
45-
// text: '中作业文档',
46-
// link: '/25spring/middle_homework/document'
47-
// },
48-
// {
49-
// text: 'Web API 文档',
50-
// link: '/25spring/middle_homework/api'
51-
// },
52-
// {
53-
// text: 'Git 基础',
54-
// link: '/25spring/middle_homework/git'
55-
// },
56-
// {
57-
// text: '常见问题',
58-
// link: '/25spring/middle_homework/faq'
59-
// }
60-
// ]
61-
// },
41+
{ text: '中作业',
42+
items: [
43+
{
44+
text: '中作业文档',
45+
link: '/26spring/middle_homework/document'
46+
},
47+
{
48+
text: 'Web API 文档',
49+
link: '/26spring/middle_homework/api'
50+
},
51+
{
52+
text: 'Git 基础',
53+
link: '/26spring/middle_homework/git'
54+
},
55+
{
56+
text: '常见问题',
57+
link: '/26spring/middle_homework/faq'
58+
}
59+
]
60+
},
6261
// {
6362
// text: "知识相关问题",
6463
// items: [
@@ -78,10 +77,10 @@ export default defineConfig({
7877
text: '上机作业参考答案',
7978
link: 'https://pku-software.github.io/homework-answer/'
8079
},
81-
// {
82-
// text: '大作业文档',
83-
// link: 'https://pku-software.github.io/project-doc/'
84-
// },
80+
{
81+
text: '大作业文档',
82+
link: 'https://pku-software.github.io/project-doc/'
83+
},
8584
{
8685
text: '谷雨同学的 C++ 教程',
8786
link: 'https://learn-cpp.guyutongxue.site/'

25spring/middle_homework/document.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ References:
8484
8585
每个文献都具有一个 `id`,它在文章中使用 `[id]` 来进行引用。我们需要找到文章中所有的 `id`,并按照 `id` 顺序(以字符串顺序为准)在文末对文献进行排列。
8686

87-
文献信息存储在JSON格式的文献合集。在文献合集中,所有的文献都保存在 `citations` 数组,数组中的每个对象代表了一个文献,并且具有字符串形式的 `id`。我们保证所有的 `id` 是无重复的。
87+
文献信息存储在 JSON 格式的文献合集。在文献合集中,所有的文献都保存在 `citations` 数组,数组中的每个对象代表了一个文献,并且具有字符串形式的 `id`, 正确的 `id` 应当仅包含数字和字母。我们保证所有的 `id` 是无重复的。
8888

89-
我们要求处理的文献有三类(其中`[]`括起来的表示需要使用具体内容替换):
89+
我们要求处理的文献有三类(其中 `[]` 括起来的表示需要使用具体内容替换):
9090

91-
+ 书籍,在文献合集中对象的字段 `type``"book"`,只具有`ISBN`号,需要程序从网络上查询合适的额外信息,最终的输出格式为 `[id] book: [作者], [书籍标题], [出版社], [出版年份]`
92-
+ 网页,在文献合集中对象的字段 `type``"webpage"`,只具有网址,同样需要程序从网络上查询,最终的输出格式为 `[id] webpage: [网页标题]. Available at [网址]`
93-
+ 文章在文献合集中对象的字段 `type``"article"`,对象的内容包含了它的全部信息,最终的输出格式为 `[id] article: [作者], [文章标题], [期刊名], [发表年份], [卷号], [期号]`
91+
+ 书籍,在文献合集中对象的字段 `type``"book"`,只具有 `ISBN` 号,需要程序从网络上查询合适的额外信息,最终的输出格式为 `[id] book: [作者], [书籍标题], [出版社], [出版年份]`,例如 `[1] book: Randal E. Bryant, David R. O'Hallaron, Computer Systems, Addison-Wesley, 2015`
92+
+ 网页,在文献合集中对象的字段 `type``"webpage"`,只具有网址,同样需要程序从网络上查询,最终的输出格式为 `[id] webpage: [网页标题]. Available at [网址]`,例如 `[2] webpage: PyTorch. Available at https://pytorch.org`
93+
+ 文章在文献合集中对象的字段 `type``"article"`,对象的内容包含了它的全部信息,最终的输出格式为 `[id] article: [作者], [文章标题], [期刊名], [发表年份], [卷号], [期号]`,例如 `[3] article: Marshall Kirk McKusick, William N. Joy, Samuel J. Leffler, Robert S. Fabry, A Fast File System for UNIX, ACM Transactions on Computer Systems, 1984, 2, 3`
9494

9595
对于网络进行查询的接口如何使用请详见[附录](#HTTP)。我们期望你补充的内容包括:
9696

@@ -99,23 +99,23 @@ References:
9999
+ `Citation` 类及其子类,用于表示文献的信息,请考虑如何尽量避免代码冗余。
100100
+ 从网络获取信息的函数(写在对应的子类中)。请注意异常处理。
101101

102-
同时,我们在 `utils.hpp` 中为大家提供了工具函数`encodeUriComponent` ,其作用见[附录HTTP部分](#HTTP)。<del>本来还提供了`readFromFile` 将文件内容完全读取到一个 `std::string` 中并返回,但是家铭助教把这几行代码给删掉了,让大家练习下怎么读文件。</del>
102+
同时,我们在 `utils.hpp` 中为大家提供了工具函数 `encodeUriComponent` ,其作用见[附录HTTP部分](#HTTP)。<del>本来还提供了 `readFromFile` 将文件内容完全读取到一个 `std::string` 中并返回,但是助教把这几行代码给删掉了,让大家练习下怎么读文件。</del>
103103

104104
最终,假设编译得到的可执行程序为`docman`,我们期望你的程序通过命令行进行处理:
105105

106106
```shell
107107
./docman OPTIONS input_file
108108
```
109109

110-
其中`input_file`为输入的文章路径(如果仅为一个`-`,则文章会从标准输入读入),`OPTIONS`则由若干个选项组成,每个选项则有以下可能:
110+
其中 `input_file` 为输入的文章路径(如果仅为一个`-`,则文章会从标准输入读入),`OPTIONS`则由若干个选项组成,每个选项则有以下可能,且顺序不定
111111

112112
+ `-c citation_path`,表示文献合集的路径,**必须填写**
113113
+ `-o output_path`,表示增加引用列表后的文章的输出路径。这个选项如果没有指定,则输出到标准输出。
114114

115-
如果选项出现冲突、出现未知选项、错误选项等,程序不应该读取任何输入,并 `std::exit(1)`。对于用户任何不合法的输入,例如不合法的文献合集、引用 id 未出现在合集中、合集对象字段不正确等,我们不会读取你输出了什么,但是也需要 `std::exit(1)`;同时如果输出到文件,则只有当输入完全正确时才创建输出文件。请保证程序的**健壮性**,助教会想出各种奇怪的 case 作为输入。我们唯一保证的是
115+
如果选项出现冲突、出现未知选项、错误选项等,程序不应该读取任何输入,并 `std::exit(1)`。对于用户任何不合法的输入,例如不合法的文献合集、引用 id 未出现在合集中、id 包含非数字字母的字符、合集对象字段不正确等,我们不会读取你输出了什么,但是也需要 `std::exit(1)`;同时如果输出到文件,则只有当输入完全正确时才创建输出文件。请保证程序的**健壮性**,助教会想出各种奇怪的 case 作为输入。我们保证的是
116116

117-
+ 用户输入的文献合集一定是一个合法JSON文件,不必担心`parse`出错;
118-
+ 文章中的`[``]`只可能出现在文献的引用中,不会出现在正常的行文里。因此不成对的括号也是需要`std::exit(1)`的。
117+
+ 用户输入的文献合集一定是一个合法 JSON 文件,不必担心 `parse` 出错;
118+
+ 文章中的 `[``]` 只可能出现在文献的引用中,不会出现在正常的行文里。因此文章中如果出现不成对的括号,属于异常情况,是需要 `std::exit(1) `的。
119119

120120
> 这种错误处理的方式是一种非常简化的方式,因为我们还没有讲异常等手段。在大作业中我们不再使用这种方式。
121121
@@ -125,8 +125,8 @@ References:
125125
2. 请注意异常处理,确保用户输入符合要求,提升程序的健壮性。
126126
3. 请注意代码的可读性,合理使用注释,提高代码的可维护性。
127127
4. 注意代码的模块化,合理划分函数,提高代码的复用性。
128-
5. 可以修改 `CMakeLists.txt`,使工程符合你的需要,包括并不限于增加依赖库、增加其他 target 等,但要保持可执行文件名称为 `docman` 不变,不修改默认二进制输出位置(对于编译文件夹是 `build` 的情况,二进制将位于 `build/docman`。这个[视频](https://www.bilibili.com/video/BV1Pg4y1U7XM?t=3072.7)介绍了 `CMake` 的使用,供参考。
129-
6. 使用 Git 等版本控制工具管理代码。**特别注意,对于本次作业(以及之后的大作业),不要把你的代码仓库设置为public的,这相当于在考场上把你的答案给每个人看一遍,助教会进行严肃处理**
128+
5. 可以修改 `CMakeLists.txt`,使工程符合你的需要,包括并不限于增加依赖库(如命令行参数解析库)、增加其他 target 等,但要保持可执行文件名称为 `docman` 不变,不修改默认二进制输出位置(对于编译文件夹是 `build` 的情况,二进制将位于 `build/docman`。这个[视频](https://www.bilibili.com/video/BV1Pg4y1U7XM?t=3072.7)介绍了 `CMake` 的使用,供参考。
129+
6. 使用 Git 等版本控制工具管理代码。**特别注意,对于本次作业(以及之后的大作业),不要把你的代码仓库设置为 public 的,这相当于在考场上把你的答案给每个人看一遍,助教会进行严肃处理**
130130

131131
## 附录
132132

@@ -160,7 +160,7 @@ JSON(JavaScript Object Notation),是 JavaScript 生成其对象时采用
160160
}
161161
```
162162

163-
在 C++ 标准库中没有 JSON 解析库,但是我们可以使用第三方库 [nlohmann/json](https://github.com/nlohmann/json) 来进行解析。这个库的一大特点就是非常符合直觉,一学就会,性能也还行。例如:
163+
在 C++ 标准库中没有 JSON 解析库,但是我们可以使用第三方库 [nlohmann/json](https://github.com/nlohmann/json) 来进行解析。这个库的一大特点就是非常符合直觉,一学就会,性能也还不错。例如:
164164

165165
```c++
166166
#include <fstream>
@@ -199,13 +199,13 @@ std::ofstream outFile{ "out.json" };
199199
outFile << data; // 输出格式为 json
200200
```
201201
202-
当然,你可以用如 `data["Never"].is_null()`、`is_boolean()`、`is_number()`、`is_object()`、`is_array()`、`is_string()` 来直接检查字段的类型,`data.contains("Never")` 来检查字段是否存在,这对于检查文献合集是否合法非常重要。
202+
当然,你可以用如 `data["Never"].is_null()`、`is_boolean()`、`is_number_integer()`、`is_object()`、`is_array()`、`is_string()` 来直接检查字段的类型,`data.contains("Never")` 来检查字段是否存在,这对于检查文献合集是否合法非常重要。
203203
204204
### <span id="HTTP">Web API</span>
205205
206206
在日常使用浏览器观看视频或阅读文章时,你是否好奇过为何能轻松访问千里之外的服务器资源?这背后正是计算机网络的核心功能。具体来说,网络通过物理介质(如光纤、电缆、无线信号)连接全球设备,并借助路由交换技术,确保数据能够跨越不同地理位置的节点,最终准确送达目标机器。全球最大的互联网络称为"因特网"(Internet),其中每台设备都通过路由器分配的IP地址进行唯一标识。
207207
208-
不过,可以注意到我们在访问网站时通常不会输入 IP 地址,而是输入一个形如 `baidu.com` 的形式(即域名)。实际上,这个字符串会先经由附近的 DNS 服务器进行解析,解析为 IP 地址,再访问这个 IP 地址。事实上,域名后面通常还会跟着 `/AA/BB`,构成一整个URL,例如我们的课程通知网页形如 `pku-software.github.io/25spring/notices.html`;这时 `/AA/BB` 则由服务器端进行解析,来确定客户端在请求什么服务。
208+
不过,可以注意到我们在访问网站时通常不会输入 IP 地址,而是输入一个形如 `baidu.com` 的形式(即域名)。实际上,这个字符串会先经由附近的 DNS 服务器进行解析,解析为 IP 地址,再访问这个 IP 地址。事实上,域名后面通常还会跟着 `/AA/BB`,构成一整个URL,例如我们的课程通知网页形如 `pku-software.github.io/26spring/notices.html`;这时 `/AA/BB` 则由服务器端进行解析,来确定客户端在请求什么服务。
209209
210210
然而,到此为止事实上只是各个机器可以互相发送接收数据;为了让机器互相知道发送的数据如何解读,就需要各方共同遵守一个规定,这个规定就称为“协议”(Protocol)。HTTP(HyperText Transfer Protocol,超文本传输协议)就是这样一种协议。不过,我们不需要你去手写如何将你的数据组装为 HTTP 数据或者反之,而是可以直接使用 C++ 的一个[HTTP 库](https://github.com/yhirose/cpp-httplib)来进行:
211211
@@ -216,10 +216,10 @@ httplib::Client client{ "http://<IP 地址或者域名>" }; // 与该 IP 地址
216216
// 在我们的utils.hpp直接定义了 API_ENDPOINT 常量,可以直接client{ API_ENDPOINT }.
217217
```
218218

219-
> 特别地,为了减少库依赖,我们这里使用的不是 `https:``https:` 会对数据进行加解密,是安全的(这个 `s` 就是 safe 的意思)。除了我们提供的域名,如果一个网页使用 `http://`,那么就要十分小心了,因为所有的信息都会明文传输。因为这个作业使用的 API 不会涉及到敏感信息,所以你无须担忧这个作业中使用 `http://` 的安全性。
219+
> 特别地,为了减少库依赖,我们这里使用的不是 `https:``https:` 会对数据进行加解密,是安全的(这个 `s` 就是 safe 的意思)。除了我们提供的域名,如果一个网页使用 `http://`,那么就要十分小心了,因为所有的信息都会明文传输。因为本作业使用的 API 不会涉及到敏感信息,所以你无须担忧本作业中使用 `http://` 的安全性。
220220
<!-- 如果你在校内,那么我们的域名在将信息中转到校外之前会帮你把服务转为 `https`,此时信息仅在校园网内部进行明文传输。 -->
221221
222-
HTTP 内规定了客户端对服务器的几种操作,最重要的两种就是 `GET``POST`,它们没有特别本质的区别,但是约定俗成地,前者在 URL 中携带参数(例如百度搜索东西就是 `baidu.com/s?wd=关键字`,这里 `?` 后面就是参数),并表示一些读取操作;后者在报文内携带参数,从而不会在网址本身中保存状态。
222+
HTTP 内规定了客户端对服务器的几种操作,最重要的两种就是 `GET``POST`,它们没有特别本质的区别,但是约定俗成地,`GET`URL 中携带参数时使用(例如百度搜索东西就是 `baidu.com/s?wd=关键字`,这里 `?` 后面就是参数),并表示一些读取操作;`POST` 在报文内携带参数,从而不会在网址本身中保存状态。
223223

224224
我们在 `http://docman.zhuof.wang` 提供了 API 查询接口,方便大家查询信息。我们统一使用 `GET` 方法即可,如下:
225225

@@ -243,7 +243,7 @@ if (result && result->status == httplib::OK_200) {
243243

244244
> 另一种常见的状态码是 `404`,即未找到相关资源。
245245
246-
事实上返回的数据可能会是 HTML 等格式来供浏览器进行解析,但为了同学们的编码方便,我们将返回的报文格式设置为了 JSON 格式。大家将 `result->body` 视作一个内部为 JSON 的字符串即可,详细文档参见 [Web API 文档](./api)
246+
事实上返回的数据可能会是 HTML 等格式来供浏览器进行解析,但为了同学们的编码方便,我们将返回的报文格式设置为了 JSON 格式。大家将 `result->body` 视作一个格式为 JSON 的字符串即可,可以利用 JSON 解析的方式进行操作,详细文档参见 [Web API 文档](./api)
247247

248248
### <span id="git">Git</span>
249249

@@ -308,6 +308,6 @@ git config --global --unset https.proxy
308308

309309
![submit 3](assets/submit-3.png)
310310

311-
点击最后的 Generate,会弹出一个文本框,妥善保存其中的 `github_pat_...` 这串内容这就是我们用于访问你的仓库的**用户令牌**
311+
点击最后的 Generate,会弹出一个文本框,妥善保存其中的 `github_pat_...` 这串内容这就是我们用于访问你的仓库的**用户令牌**
312312

313313
将你的 **GitHub 用户名****GitHub 仓库名**和刚刚生成的**用户令牌**提交到教学网 <ins>*课程作业-中作业*</ins> 处。

25spring/middle_homework/faq.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ cmake -B build
1010
cmake --build build
1111
```
1212

13-
**Q2**: Windows 下编译不过,报错中有 “找不到 read 符号”等相似字眼
13+
**Q2**: Windows 下编译不过,报错中有 “找不到 read 符号” 等相似字眼
1414

1515
**A2**: `CMakeLists.txt` 中需要有如下的语句,在 Windows 下链接到系统网络库 `ws2_32`
1616
```cmake
@@ -124,4 +124,4 @@ if (!file.is_open()) {
124124
**A1**:
125125
126126
- 确保能看到文件后缀名:如果你使用 Windows 系统,你需要确保文件资源管理器设置为显示文件扩展名。打开文件资源管理器,选择“查看”标签页,然后勾选“文件扩展名”选项。如果你使用 Mac,你可以在 Finder 中选择“Finder”菜单,点击“偏好设置”,然后在“高级”标签中勾选“显示所有文件扩展名”。
127-
- 创建JSON文件:创建一个 txt 文件,写入 JSON 内容,然后将后缀名改成 json。当然如果你可以在保存的时候选择需要创建的后缀名,直接保存为 json 格式即可。
127+
- 创建 JSON 文件:创建一个 txt 文件,写入 JSON 内容,然后将后缀名改成 json。当然如果你可以在保存的时候选择需要创建的后缀名,直接保存为 json 格式即可。

0 commit comments

Comments
 (0)