substr 函数
C++ substr 函数学习路径
substr 是 C++ 中用来截取字符串子串的重要函数。
一、substr 基础概念
函数原型
string substr(size_t pos = 0, size_t len = npos) const;
参数说明
· pos:开始位置(从0开始计数)
· len:要截取的长度(可选,默认到字符串末尾)
返回值
返回一个新的字符串,包含从 pos 开始的 len 个字符
二、学习路径与练习题
阶段1:基础用法(1-2天)
练习1:截取名字
#include <iostream> #include <string> int main() { std::string fullName = "Liu You Yi"; // 截取姓氏(前3个字符) std::string lastName = fullName.substr(0, 3); std::cout << "姓氏: " << lastName << std::endl; // 截取名字"You Yi"(从位置4开始到末尾) std::string firstName = fullName.substr(4); std::cout << "名字: " << firstName << std::endl; return 0; }
练习2:提取文件扩展名
#include <iostream> #include <string> int main() { std::string filename = "document.pdf"; // 找到点号的位置 size_t dotPos = filename.find('.'); // 检查是否找到并截取扩展名 if(dotPos != std::string::npos) { std::string extension = filename.substr(dotPos + 1); std::cout << "文件扩展名: " << extension << std::endl; } else { std::cout << "没有找到扩展名" << std::endl; } return 0; }
阶段2:中级应用(2-3天)
练习3:分割字符串
#include <iostream> #include <string> #include <vector> int main() { std::string date = "2023-08-15"; std::vector<std::string> parts; size_t start = 0; size_t end = date.find('-'); // 循环分割字符串 while(end != std::string::npos) { parts.push_back(date.substr(start, end - start)); start = end + 1; end = date.find('-', start); } // 添加最后一部分 parts.push_back(date.substr(start)); // 输出结果 std::cout << "年: " << parts[0] << std::endl; std::cout << "月: " << parts[1] << std::endl; std::cout << "日: " << parts[2] << std::endl; return 0; }
练习4:提取URL各部分
#include <iostream> #include <string> int main() { std::string url = "https://www.example.com:8080/path/to/page"; // 提取协议(https) size_t protocolEnd = url.find("://"); std::string protocol = url.substr(0, protocolEnd); // 提取域名和端口 size_t domainStart = protocolEnd + 3; size_t pathStart = url.find('/', domainStart); std::string domainAndPort = url.substr(domainStart, pathStart - domainStart); // 提取路径 std::string path = url.substr(pathStart); std::cout << "协议: " << protocol << std::endl; std::cout << "域名和端口: " << domainAndPort << std::endl; std::cout << "路径: " << path << std::endl; return 0; }
阶段3:进阶应用(3-5天)
练习5:实现简单文本高亮
#include <iostream> #include <string> std::string highlightText(const std::string& text, const std::string& keyword) { std::string result; size_t pos = 0; size_t keywordPos = text.find(keyword); while(keywordPos != std::string::npos) { // 添加关键词前的文本 result += text.substr(pos, keywordPos - pos); // 添加高亮关键词 result += "[" + text.substr(keywordPos, keyword.length()) + "]"; // 更新位置 pos = keywordPos + keyword.length(); keywordPos = text.find(keyword, pos); } // 添加剩余文本 result += text.substr(pos); return result; } int main() { std::string content = "C++ is a powerful language. C++ is fast."; std::string highlighted = highlightText(content, "C++"); std::cout << "高亮结果:\n" << highlighted << std::endl; return 0; }
练习6:密码隐藏显示
#include <iostream> #include <string> std::string hidePassword(const std::string& password, int showChars = 2) { if(password.length() <= showChars) { return password; // 太短不隐藏 } // 显示前showChars个字符,其余用*代替 return password.substr(0, showChars) + std::string(password.length() - showChars, '*'); } int main() { std::string password = "mySecret123"; std::cout << "完整密码: " << password << std::endl; std::cout << "隐藏后: " << hidePassword(password) << std::endl; std::cout << "显示3个字符: " << hidePassword(password, 3) << std::endl; return 0; }
三、常见错误及解决方法
错误1:位置超出范围
std::string str = "hello"; // std::string sub = str.substr(10, 2); // 抛出异常! // 正确做法:先检查长度 if(str.length() > 10) { std::string sub = str.substr(10, 2); }
错误2:忘记检查find结果
std::string email = "test@example"; size_t atPos = email.find('@'); // std::string domain = email.substr(atPos + 1); // 如果没找到@会出错 // 正确做法 if(atPos != std::string::npos) { std::string domain = email.substr(atPos + 1); }
错误3:混淆参数顺序
std::string date = "2023-08-15"; // std::string month = date.substr(5, 2); // 正确:从位置5截取2个字符 // std::string wrong = date.substr(2, 5); // 语义错误(虽然语法正确)
四、综合练习
练习7:提取CSV文件数据
#include <iostream> #include <string> #include <vector> std::vector<std::string> parseCSVLine(const std::string& line) { std::vector<std::string> fields; size_t start = 0; size_t end = line.find(','); while(end != std::string::npos) { fields.push_back(line.substr(start, end - start)); start = end + 1; end = line.find(',', start); } fields.push_back(line.substr(start)); return fields; } int main() { std::string csvLine = "Liu You Yi,14,Beijing,C++ Programming"; std::vector<std::string> data = parseCSVLine(csvLine); std::cout << "姓名: " << data[0] << std::endl; std::cout << "年龄: " << data[1] << std::endl; std::cout << "城市: " << data[2] << std::endl; std::cout << "兴趣: " << data[3] << std::endl; return 0; }
五、学习建议
1.循序渐进:从简单截取开始,逐步尝试复杂的分割和处理
2.多调试:使用cout输出中间结果,观察substr的行为
3.结合find:大多数实际应用中substr都是和find一起使用
4.边界检查:始终检查位置是否有效,避免程序崩溃
记住:substr 是处理字符串的强大工具,掌握它能让你的文本处理能力大大提升!加油练习!