C++课程信息解析代码修复:提取课程名、CRN、上课时间与日期
问题:修复课程信息提取的C++代码
现有多行课程信息遵循以下格式:
- 课程名(空格分隔)后接制表符/多个空格
- 随后是5位CRN编号
- 接着是上课日期(1个或2个,多日期用「逗号+空格」分隔)
- 再接制表符/多个空格
- 最后是时间(格式为「时:分 AM/PM」)
需要编写C++代码提取这些信息并按指定格式输出,但当前代码运行后输出不符合预期,请求修复。
示例输入
Structures of Computer Science 10916 Mon, Thu 8:30 AM Computer Science I Lab 49835 Tue 1:00 PM
期望输出
Description: Structures of Computer Science CRN: 10916 Meeting Days: Mon, Thu Meeting Time: 8:30 AM
当前错误代码
#include <iostream> #include <sstream> #include <string> #include <vector> using namespace std; // Function to parse the line and extract relevant information void parseLine(const string& line) { stringstream ss(line); string token; vector<string> tokens; // Split the line into tokens while (ss >> token) { tokens.push_back(token); } // Output the relevant information if (tokens.size() >= 4) { // Extract the description string description; for (size_t i = 0; i < tokens.size() - 3; ++i) { description += tokens[i]; if (i < tokens.size() - 4) { description += " "; } } // Extract CRN string crn = tokens[tokens.size() - 3]; // Extract meeting days string meetingDays = tokens[tokens.size() - 2]; // Extract meeting time string meetingTime = tokens[tokens.size() - 1]; // Output parsed information cout << "Description: " << description << endl; cout << "CRN: " << crn << endl; cout << "Meeting Days: " << meetingDays << endl; cout << "Meeting Time: " << meetingTime << endl; } else { cout << "Invalid input line!" << endl; } } int main() { string line = "Structures of Computer Science 10916 Mon, Thu 8:30 AM"; // Parse and output information parseLine(line); return 0; }
当前错误输出
Description: Structures of Computer Science 10916 Mon, CRN: Thu Meeting Days: 8:30 Meeting Time: AM
修复方案
错误原因
原代码通过空格分割所有内容,导致以下问题:
- 带空格的日期(如
Mon, Thu)被拆成两个独立token - 带空格的时间(如
8:30 AM)被拆成两个独立token - 错误地将CRN和部分日期归入课程名,最终所有字段的提取逻辑完全错位
修复后的代码
#include <iostream> #include <string> #include <cctype> using namespace std; // 去除字符串前后的空白字符(空格、制表符) string trim(const string& s) { size_t start = s.find_first_not_of(" \t"); size_t end = s.find_last_not_of(" \t"); return (start == string::npos) ? "" : s.substr(start, end - start + 1); } // 解析单行课程信息 void parseLine(const string& line) { // 查找5位CRN的起始位置(确保前后是空白字符,避免课程名含5位数字的情况) size_t crnStart = string::npos; for (size_t i = 0; i <= line.size() - 5; ++i) { bool isAllDigits = true; for (size_t j = 0; j < 5; ++j) { if (!isdigit(line[i + j])) { isAllDigits = false; break; } } if (isAllDigits && (i == 0 || isspace(line[i-1])) && (i+5 == line.size() || isspace(line[i+5]))) { crnStart = i; break; } } if (crnStart == string::npos) { cout << "Invalid input line!" << endl; return; } // 提取课程名(去除前后空白) string description = trim(line.substr(0, crnStart)); // 提取5位CRN string crn = line.substr(crnStart, 5); // 处理CRN之后的剩余内容 string rest = trim(line.substr(crnStart + 5)); // 查找时间部分(以" AM"或" PM"为标识) size_t timeMarkerPos = rest.find(" AM"); if (timeMarkerPos == string::npos) { timeMarkerPos = rest.find(" PM"); } if (timeMarkerPos == string::npos) { cout << "Invalid input line!" << endl; return; } // 提取日期和时间(去除前后空白) string meetingDays = trim(rest.substr(0, timeMarkerPos)); string meetingTime = trim(rest.substr(timeMarkerPos)); // 输出解析结果 cout << "Description: " << description << endl; cout << "CRN: " << crn << endl; cout << "Meeting Days: " << meetingDays << endl; cout << "Meeting Time: " << meetingTime << endl; } int main() { // 测试第一行 string line1 = "Structures of Computer Science 10916 Mon, Thu 8:30 AM"; parseLine(line1); cout << endl; // 测试第二行 string line2 = "Computer Science I Lab 49835 Tue 1:00 PM"; parseLine(line2); return 0; }
修复思路
- 基于CRN特征定位:利用CRN是固定5位数字的特点,遍历字符串找到其位置,确保前后为空白字符以避免误判
- 分割字段:
- 课程名:从开头到CRN起始位置的内容,去除前后空白
- CRN:直接截取5位数字
- 剩余内容:以时间标识(
AM/PM)为分界,前面是日期,后面是时间
- trim函数辅助:去除各字段前后的空白字符,保证输出整洁
内容的提问来源于stack exchange,提问作者SUP
相关产品推荐
相关产品推荐

