Stanford CS106L Assign 1 24 Fall

399 阅读5分钟

preview

本来不是很想写这些博客的,但是觉得不写博客就难以深化理解所学到的东西,于是本博客将会从环境配置(仅assign1会有,而且只提及看文档难以理解的重点),题目详解实现细节收获等角度来展开。

特别声明:有关环境方面的环境搭建,本文一律采用安装在默认C盘下。

本系列博客是基于 Stanford CS106L 的课程设计作业所展开的。具体页面如下:

image.png

建议fork仓库到本地进行学习

环境配置

官方文档使用vscode进行编辑,编译,运行测试样例,本次assign完成也是使用vscode。官网配置文档给出的.vscode文件并不是很好用,建议使用这里给出的.vscode配置文件配置相应的vscode。

在配置好vscode之后我们需要搭建编译套件和自动运行环境(也就是C++环境和python3.8环境),这里使用msys2进行配置,首先在msys2官网找到安装向导之后根据官网给出的参考手册,所有设置保持默认即可。

为了保持方便,可以将msys2配置到环境变量当中

  • 找到 MSYS 安装目录(通常是 C:\msys64 或者您指定的其他路径)。

  • 设置环境变量

    • 打开 Windows 的“系统属性”>“高级”>“环境变量”。
    • 在系统环境变量中,将 MSYS 的路径(如 C:\msys64\usr\bin)添加到 Path 环境变量中。

如下图所示 Screenshot 2024-11-04 231245.png

检查更新msys2

在安装好msys2后执行

pacman -Syu

更新msys2当中的软件包 image.png

安装MinGw

在msys2的终端当中执行

pacman -S mingw-w64-x86_64-gcc

安装python3.8

  • python官网下载安装python,保持默认路径。
  • 接着在路径当中找到python38的位置,按照上述说明配置到环境变量当中即可

题目详解

image.png 课程题目为SimpleEnroll,实际做起来也很简单 assign1创建了一个Course结构体,包含title,units,quarter三个变量,该结构体用来存储课程信息。 课程目的是将course.csv的offered course和not offered course分开

对于本assign而言我们需要完成下面三个目标

  • 将course.csv当中的内容解析到Course数组当中
  • 将Course数组当中的offered course写入到courses_offered.csv当中,并且从数组中删除这些课程
  • 将剩余的课程写入courses_not_offered.csv当中

主要归结下来就是

  • fstream的应用
  • getline的使用

实现细节

主要就是三个函数,但是需要注意将函数的参数改为引用。

image.png

parse_csv

void parse_csv(std::string filename, std::vector<Course>& courses) {
  /* (STUDENT TODO) Your code goes here... */

  std::ifstream input(filename);
  if (!input.is_open()) {
    throw std::runtime_error("Could not open:" + filename);
  }
  string header;
  getline(input, header);
  string line;
  while (getline(input, line)) {
    vector<string> fields = split(line, ',');
    if (fields.size() == 3) {
      courses.push_back(Course{fields[0], fields[1], fields[2]});
    }
  }
  input.close();
}

这里思路是首先用ifstream打开course.csv文件,接着把header部分去掉,然后使用getline从文件流当中逐行读取并且将这个字符串利用utils.cpp当中提供的split函数转化为独立的字符串,接着将这三个字符串push_back到Course数组当中去即可,最后关闭文件流

write_course_offered

void write_courses_offered(std::vector<Course>& all_courses) {
  /* (STUDENT TODO) Your code goes here... */
    std::ofstream output("student_output/courses_offered.csv");
    std::ifstream input("courses.csv");
    if (!output.is_open() || !input.is_open()) {
        throw std::runtime_error("Could not open file");
    }
    string header;
    getline(input, header);
    output << header << std::endl;
    string line;
    vector<Course> offered_courses;
    for(auto&c:all_courses)
    {
      if(c.quarter!="null")
      {
      offered_courses.push_back(c);
      output << c.title << "," << c.number_of_units << "," << c.quarter << std::endl;
      }
    }
    for(auto&c:offered_courses)
    {
      delete_elem_from_vector(all_courses, c);
    };
}

这里思路处理和上面很像,不过是使用ofstream向文件流当中写入数据,但是需要从course.csv当中读取header写入文件流当中,最后再利用utils.cpp当中的delete_elem_from_vector删除已经添加的课程。

write_courses_not_offerd

void write_courses_not_offered(std::vector<Course>& unlisted_courses) {
  /* (STUDENT TODO) Your code goes here... */
    std::ofstream output("student_output/courses_not_offered.csv");
    std::ifstream input("courses.csv");
    if (!output.is_open()||!input.is_open()) {
        throw std::runtime_error("Could not open file");
    }
    string header;
    getline(input, header);
    output << header << std::endl;
    input.close();
    for(auto&c:unlisted_courses)
    {
      output << c.title << "," << c.number_of_units << "," << c.quarter << std::endl;
    }  
    output.close();
}

实现和上面类似。

收获

对于getline的使用变得熟练多了,还有就是对于文件流的应用变得熟练多了,这里可以参考ifstreamofstream 的说明文档进一步了解。

☞ i和o 是流对对象产生的效果,i就是这个流是用来写入的,o表示这个流是用来写出的,如果使用i流表示我们要将东西写入到对象当中,如果是o流,表示我们要将对象当中的东西写出

在这个过程当中,读README.md是一件很痛苦的事情,更为痛苦的事情是搭建环境,我的电脑当中已经有了自己之前配置的MinGw和py3.11环境,但是环境和这个课程不兼容,只好全部重新配。说真的,配置环境太难了。

还有,写这个博客花了一个小时,写完觉得思路清晰了不少,感觉写博客真的很锻炼思路,虽然我有时很懒,懒得写那么详细,思考那么深入。但是还是要努力写好每一篇文章,这也是对自己的尊重。

写在后面

欢迎指出错误!

欢迎交流联系2310460@mail.nankai.edu.cn

欢迎关注我的 github

欢迎一起进步!