在C++ 11中,string :: c_str()指向的数组中的字符是否可以被更改?

use*_*157 14 c++ string c++11

std::string::c_str() 返回一个指向数组的指针,该数组包含一个以空字符结尾的字符序列(即一个C字符串),表示字符串对象的当前值.

在C++ 98中,要求"程序不得改变此序列中的任何字符".通过返回const char*来鼓励这一点.

在C++ 11中,"指针返回指向字符串对象当前使用的内部数组,以存储符合其值的字符",我相信不删除修改其内容的要求.这是真的?

这段代码在C++ 11中是否正常?

#include<iostream>
#include<string>
#include<vector>
using namespace std;

std::vector<char> buf;

void some_func(char* s)
{
    s[0] = 'X'; //function modifies s[0]
    cout<<s<<endl;
}

int main()
{
    string myStr = "hello";
    buf.assign(myStr.begin(),myStr.end());
    buf.push_back('\0');
    char* d = buf.data();   //C++11
    //char* d = (&buf[0]);  //Above line for C++98
    some_func(d);   //OK in C++98
    some_func(const_cast<char*>(myStr.c_str())); //OK in C++11 ?
    //some_func(myStr.c_str());  //Does not compile in C++98 or C++11
    cout << myStr << endl;  //myStr has been modified
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Bor*_*der 26

3要求:程序不得更改存储在字符数组中的任何值.

该要求在n3337草案中仍然存在(与已发布的C++ 11标准最相似的工作草案是N3337)

  • 我已经证实这是在已发布的C++ 11标准(ISO/IEC 14882-2011)中. (5认同)

Pot*_*ter 5

在C++ 11中,是的限制c_str()仍然有效.(注意返回类型是const,所以这个函数实际上不需要特别的限制.const_cast你的程序中有一个很大的红旗.)

但至于operator[]它似乎只是由于编辑错误才有效.由于C++ 14的标点符号更改,您可以修改它.所以解释取决于你.当然这样做非常普遍,没有任何库实现都不敢破解它.

C++ 11措辞:

返回:*(begin()+ pos)如果pos <size(),否则引用类型为T的对象,其值为charT(); 参考值不得修改.

C++ 14措辞:

如果pos <size(),则返回:*(begin()+ pos).否则,返回对charT类型的对象的引用,其值为charT(),其中修改对象会导致未定义的行为.

您可以c_str()作为只读参考传递给期望C字符串的函数,正如其签名所暗示的那样.期望读写引用的函数通常期望给定的缓冲区大小,并且能够通过NUL在该缓冲区内写入来调整字符串的大小,这些std::string实现实际上不支持.如果你想这样做,你需要resize在字符串中包含你自己的NUL终结符,然后传递& s[0]哪个是读写引用,然后resize再次删除你的NUL终结符并将终止的责任交还给库.