std::revers(ed) std::string是否在开始处包含空字符?

C++14 - Does an std::revers(ed) std::string contain a null character at the start?

本文关键字:std 开始 字符 包含空 string revers ed 是否      更新时间:2023-10-16

如果我在std::string变量上使用std::reverse,我可以安全地假设空字符''将被放置在字符串的开头吗?

不,它将不包含NUL字节(除非您在那里放置一个)。前向迭代器也不会包含NUL字节,它只会迭代字符串本身的字符。

NUL字节保证超过.c_str().data()的末尾,但是

示例程序:

#include <string>
#include <iostream>
#include <algorithm>
int main() {
    std::string s = "Hello";
    std::cout << "Forwards:n";
    for (auto i = std::begin(s), e = std::end(s); i != e; ++i) {
        std::cout << *i << ' ' << static_cast<int>(*i) << 'n';
    }
    std::cout << "Backwards:n";
    std::reverse(std::begin(s), std::end(s));
    for (auto i = std::begin(s), e = std::end(s); i != e; ++i) {
        std::cout << *i << ' ' << static_cast<int>(*i) << 'n';
    }
    return 0;
}
输出:

<>之前转发:H 72e 101l 108年l 108年111年阿向后:111年阿l 108年l 108年e 10172 H

我可以安全地假设空字符''将被放置在字符串的开头吗?

。只有当您在原始字符串的最后一个字符中放置了一个空字符时才会出现这种情况。

与大多数容器不同,std::string实际上在end()迭代器下有数据。(该标准使得解引用end()仍然是非法的,但实际上没有办法避免它)。

.size()=Nstd::stringN+1个条目,最后一个是''。第一个N条目也可以包含'',但最后一个是自动放在那里的。

begin()返回一个迭代器到第一个条目,而end()返回到one-past-the-end(实际上,返回到终止的'',但您不允许在标准下检查(这意味着调试迭代器可以捕获该错误,并告诉您犯了错误))。

同时,.data().c_str()返回原始缓冲区的指针。与.c_str()阅读''"过去的结束"是合法的。有趣的是,对于.data(),读取超过字符串末尾的''合法的,因为只有可以迭代的元素才允许被读取。在标准下是合法的,但不太可能在''所在的位置出现未初始化字符(甚至是页面错误),直到第一次调用.c_str()发生。在c++ 11中都不允许分配。(我不保证c++ 03或更早版本的c++)。

因此,

rbegin()rend()也返回字符串内的元素,不包括终止''的元素,reverse(begin(), end())再次操作字符串内的元素,不包括终止''的元素。

如果在字符串中嵌入'' ,它们不会终止字符串。如果您将.c_str()传递给const char* API,它将假定字符串结束,但由std::string管理的实际缓冲区将超过您注入的''。并且end()将继续指向字符串的"最后一个"元素,而不是指向您的''

std::string将不包含结束null字符,您正在考虑将以空结束的字符数组用作字符串。