不溜過客 2025-05-23 23:55 采纳率: 98.4%
浏览 48
已采纳

C++中如何使用string的substr函数截取子字符串?

在C++中使用`std::string`的`substr`函数时,常见的技术问题是:如何正确设置起始位置和截取长度以避免异常或未定义行为? `substr`函数原型为`string substr(size_t pos = 0, size_t len = npos) const;`,其中`pos`是起始索引,`len`是子字符串长度。如果`pos`超出字符串范围,会抛出`out_of_range`异常;若`len`超出剩余字符长度,则自动截取到字符串末尾。 例如: ```cpp std::string str = "Hello, World!"; try { std::string sub = str.substr(7, 5); // 从索引7开始,截取5个字符,结果为"World" std::cout << sub << std::endl; } catch (const std::out_of_range& e) { std::cerr << "Error: " << e.what() << std::endl; } ``` 问题:当`pos`等于字符串长度时,调用`substr(pos, len)`会返回什么?是否会抛出异常?(提示:不会抛出异常,返回空字符串)。
  • 写回答

1条回答 默认 最新

  • 马迪姐 2025-05-23 23:56
    关注

    1. 基础理解:`std::string::substr`函数的定义与行为

    `std::string::substr` 是 C++ 标准库中用于从字符串中提取子串的成员函数。其原型为:

    string substr(size_t pos = 0, size_t len = npos) const;

    其中,`pos` 表示起始索引,`len` 表示要截取的长度。

    • 如果 `pos` 超出字符串范围(即 `pos > str.length()`),会抛出 `std::out_of_range` 异常。
    • 如果 `len` 超出了剩余字符的数量,则自动调整为从 `pos` 到字符串末尾的所有字符。

    例如以下代码:

    std::string str = "Hello, World!";
        std::string sub = str.substr(7, 5); // 结果为 "World"

    上述代码从索引 7 开始,截取了 5 个字符。

    2. 深入分析:当 `pos` 等于字符串长度时的行为

    假设我们有如下代码:

    std::string str = "Hello, World!";
        std::string sub = str.substr(str.length(), 5);

    在这种情况下,`pos` 等于字符串的长度(即 13)。根据 `substr` 的定义:

    1. `pos` 必须小于或等于字符串的长度,因此不会抛出异常。
    2. 由于从索引 13 开始没有字符可以截取,因此返回空字符串 `""`。

    总结这一行为的关键点是:`substr(pos, len)` 在 `pos == str.length()` 时,不会抛出异常,而是直接返回空字符串。

    3. 实践案例:避免异常和未定义行为

    在实际开发中,为了避免因错误设置 `pos` 和 `len` 导致的异常或未定义行为,可以通过以下方式检查输入参数:

    场景解决方案
    `pos` 超出范围在调用 `substr` 之前,检查 `pos <= str.length()`。
    `len` 超出剩余字符数量将 `len` 设置为 `std::min(len, str.length() - pos)`。

    以下是安全调用的代码示例:

    std::string safe_substr(const std::string& str, size_t pos, size_t len) {
        if (pos > str.length()) {
            throw std::out_of_range("Position out of range");
        }
        return str.substr(pos, std::min(len, str.length() - pos));
    }

    4. 流程图:`substr` 函数的行为逻辑

    通过流程图展示 `substr` 的执行逻辑:

    ```mermaid
    graph TD;
        A[开始] --> B{pos <= str.length()};
        B --是--> C{len <= str.length() - pos};
        C --是--> D[返回子串];
        C --否--> E[调整 len 至最大值];
        B --否--> F[抛出异常];
    ```

    此流程图清晰地展示了 `substr` 函数在不同条件下的执行路径。

    5. 高级讨论:性能与边界条件

    对于大规模字符串操作,`substr` 的性能可能成为瓶颈。特别是在频繁调用时,应尽量减少不必要的拷贝操作。此外,还需注意以下边界条件:

    • `pos` 和 `len` 的类型为 `size_t`,确保它们始终为非负值。
    • 避免使用过大的 `len` 值,防止内存分配失败。

    以下代码展示了如何优化性能:

    std::string_view view_str = str;
    std::string_view sub_view = view_str.substr(pos, len);

    通过 `std::string_view` 避免了额外的字符串拷贝。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 10月23日
  • 创建了问题 5月23日