C++怎么截取字符串 C++ substr函数参数越界处理

来源:个人站长作者:松本一香头衔:网络博主
导读:本期聚焦于小伙伴创作的《C++怎么截取字符串 C++ substr函数参数越界处理》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++怎么截取字符串 C++ substr函数参数越界处理》有用,将其分享出去将是对创作者最好的鼓励。

在C++标准库中,std::stringsubstr函数是实现字符串截取的核心接口,它的使用场景非常广泛,比如提取文件路径中的文件名、解析协议头中的字段等。不过很多开发者在使用时容易忽略参数边界问题,导致程序运行时出现未定义行为。

C++怎么截取字符串 C++ substr函数参数越界处理

substr函数基本用法

substrstd::string类的成员函数,原型如下:

// 函数原型
std::string substr(size_t pos = 0, size_t count = npos) const;

它的两个参数含义分别是:

  • pos:截取的起始位置,从0开始计数,必须是有效位置或者等于字符串的长度
  • count:需要截取的字符数量,默认值是std::string::npos,表示截取到字符串末尾

下面是一个基础的使用示例:

#include <iostream>
#include <string>

int main() {
    std::string str = "hello world";
    // 从位置2开始截取3个字符
    std::string sub1 = str.substr(2, 3);
    // 从位置6开始截取到末尾
    std::string sub2 = str.substr(6);
    std::cout << "sub1: " << sub1 << std::endl; // 输出 llo
    std::cout << "sub2: " << sub2 << std::endl; // 输出 world
    return 0;
}

参数越界的触发场景

substr的参数越界主要分两种情况,只要满足其中一种就会触发未定义行为:

1. 起始位置pos超过字符串长度

pos的值大于当前字符串的长度时,就会触发越界。比如字符串长度是5,传入的pos是6,此时就会报错。

#include <iostream>
#include <string>

int main() {
    std::string str = "test"; // 长度为4,有效pos范围是0-4
    // pos=5超过字符串长度,触发越界
    std::string sub = str.substr(5, 2); 
    return 0;
}

2. 截取长度count超出剩余字符数

pos是有效位置,但pos + count超过了字符串的长度,且count不是std::string::npos时,也会触发越界。比如字符串长度是4,pos是2,count是3,此时剩余字符只有2个,截取的字符数超出剩余量就会越界。

#include <iostream>
#include <string>

int main() {
    std::string str = "test"; // 长度为4
    // pos=2,剩余字符是2个,count=3超出剩余量,触发越界
    std::string sub = str.substr(2, 3);
    return 0;
}

不同编译器的越界表现

参数越界属于C++标准中的未定义行为,不同编译器的处理方式会有差异:

  • 在GCC编译器下,通常会直接抛出std::out_of_range异常,程序终止运行
  • 在MSVC编译器下,调试模式会触发断言失败,弹出错误提示; release模式可能不会报错,但会返回不可预期的结果
  • 部分老旧编译器可能不会做任何检查,直接返回错误的字符串内容,导致后续逻辑出错

避免参数越界的处理方案

为了避免substr参数越界,我们可以在使用前做参数校验,调整参数到合法范围:

方案一:手动校验参数

先判断pos是否超过字符串长度,再计算实际可截取的长度,避免传入非法参数。

#include <iostream>
#include <string>
#include <algorithm>

std::string safe_substr(const std::string& str, size_t pos, size_t count = std::string::npos) {
    // 如果起始位置超过字符串长度,返回空字符串
    if (pos >= str.size()) {
        return "";
    }
    // 如果count是npos或者pos+count超过字符串长度,调整count为剩余字符数
    if (count == std::string::npos || pos + count > str.size()) {
        count = str.size() - pos;
    }
    return str.substr(pos, count);
}

int main() {
    std::string str = "hello";
    // 正常截取
    std::cout << safe_substr(str, 1, 3) << std::endl; // 输出 ello
    // 起始位置越界,返回空
    std::cout << safe_substr(str, 10, 2) << std::endl; // 输出 空
    // 截取长度超出剩余量,自动调整到末尾
    std::cout << safe_substr(str, 3, 5) << std::endl; // 输出 lo
    return 0;
}

方案二:捕获异常

如果确定编译器会在越界时抛出异常,也可以使用try-catch块捕获std::out_of_range异常来处理错误。

#include <iostream>
#include <string>

int main() {
    std::string str = "hello";
    try {
        std::string sub = str.substr(6, 2);
        std::cout << sub << std::endl;
    } catch (const std::out_of_range& e) {
        std::cout << "截取字符串参数越界: " << e.what() << std::endl;
    }
    return 0;
}

注意事项

需要注意pos等于字符串长度是合法的情况,此时无论count是多少,都会返回空字符串,不会触发越界。比如str.substr(str.size(), 5)的返回结果是空字符串,这是符合标准的正常行为。

在实际开发中,建议优先使用参数校验的方案,因为未定义行为的不确定性会带来隐藏的bug,提前校验参数可以让代码更健壮。

C++_substr字符串截取参数越界异常处理修改时间:2026-07-22 05:57:30

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。