首先从标准中摘录一些:
规格string::operator[]():
const_reference运算符[](size_type pos)const;
reference operator [](size_type pos);
需要:pos <= size().
返回:*(begin()+ pos)如果pos <size(),否则引用类型为T的对象,其值为charT(); 参考值不得修改.
复杂性:恒定时间.
规格string::c_str()和string::data():
const charT*c_str()const noexcept;
const charT*data()const noexcept;
返回:指针p,p + i == &operator[](i)对于[0,size()]中的每个i.
复杂性:恒定时间.
通过组合这两个规范,我们可以看到/ p返回的指针必须满足指定字符串的元素,并且等于,指定具有该值的对象.由于指针上的加法运算符用于获取字符串元素和最后一个对象的地址,因此它们必须位于单个数组中(您不能只使用字符串元素并在运行中创建对象,把它返还).那么可以肯定地说,在C++ 11中,保证在其底层存储中具有终止空字符吗?c_str()data()p[0...size()-1]p[size()]operator[](size())charT()charT()charT()str::string
编辑:我没有注意到我的问题的道歉是重复的.但是,我在这里得到的答案似乎与那个重复问题的答案相矛盾.
此外,我应该削弱我的假设:底层表示std::string应该保留足够的空间来保存终止空字符,并自由设置charT()值直到c_str()/ data()被调用.(即底层存储必须能够随时保留至少size()+1元素.)
我有一个std::string类的对象,我需要传递给C函数,char*通过迭代它并搜索空终止符号来操作缓冲区.
所以,我有这样的事情:
// C function
void foo(char* buf);
// C++ code
std::string str("str");
foo(&str[0]);
Run Code Online (Sandbox Code Playgroud)
假设我们使用C++ 11,因此我们保证std::string表示将具有连续存储的字符.
但我想知道是否有任何保证&str[0]会指向缓冲区结束\0?是的,有c_str成员函数,但我在谈论operator[].
有人可以引用标准吗?
示例如下:
string s1 = "abcde";
string s2(s1, s1.size()); // s1.size() = 5.
Run Code Online (Sandbox Code Playgroud)
请注意,s1.size() = 5 且最后允许的索引 = 4(对于字符“e”)。上面的代码运行良好,返回空字符串。仅当 pos = 6 时,它才会失败,并出现超出范围的异常。为什么?
根据 cppe 参考网站:
例外
3) std::out_of_range 如果 pos > other.size()
正确的异常不应该是“if pos >= other.size()”吗?
我正在使用VS2012/C++,我需要将std :: string转换为char*,我在网上找不到任何材料给出任何关于如何去做的指导.
任何代码示例和建议将不胜感激.
是的,我确实检查了其他线程,我得出了结论.我只是想让你确认一下,这样我才不会有任何误解.
Java String对象不以null结尾.
C++ std :: string对象也不是以null结尾
C字符串或C风格的字符串(如果您将(字符数组))是唯一以空值终止的字符串.
正确还是不正确?
std::string.c_str()返回一个(const char*)值.我用Google搜索,发现我可以执行以下操作:
std::string myString = "Hello World";
char *buf = &myString[0];
Run Code Online (Sandbox Code Playgroud)
这怎么可能?&myString[0]是一个类型的对象std::string,那么它如何工作?
假设我有一个非常复杂的缓冲区加扰函数,可以使用以下原型:
void do_something(char * thebuffer, int thelength);
Run Code Online (Sandbox Code Playgroud)
并且假设我需要让函数在std :: string上运行.但是std :: string.c_str()返回const char*,这是不可变的.
除了创建一个新的char*缓冲区,并将其传递给do_something之外,是否可以将do_something用于std :: string?
我的情况实际上是另一种方式(char*,int到std :: string和taking函数).
或者是绕过这个的唯一方法,就是去制作一个新的功能副本,它做同样的事情?(这真的不是很好的风格)
我试图将a转换std::string为char*(复制而不是转换),因为必须将一些数据传递给相当过时的API.
从表面上看,有很多方法可以做到这一点,但有人建议我这样做是一个看似合理的向量.但是,当我尝试这个时,结果是乱码.代码如下:
const string rawStr("My dog has no nose.");
vector<char> str(rawStr.begin(), rawStr.end());
cout << "\"" << (char*)(&str) << "\"" << endl;
Run Code Online (Sandbox Code Playgroud)
(注意令人不快的C演员 - 使用static_cast不起作用,这可能告诉我一些事情)
当我运行这个时,我得到:
"P/"
Run Code Online (Sandbox Code Playgroud)
显然不对.我看了一下gdb中的向量
(gdb) print str
$1 = std::vector of length 19, capacity 19 = {77 'M', 121 'y', 32 ' ', 100 'd', 111 'o',
103 'g', 32 ' ', 104 'h', 97 'a', 115 's', 32 ' ', 110 'n', 111 'o', 32 ' ', 110 'n',
111 'o', 115 …Run Code Online (Sandbox Code Playgroud) 我给出了一个[97, 98, 0, 99, 100]GSM 7 位编码的字节数组。这应该转换为ab@cd. 当我尝试将此给定数组附加到 a 时StringBuilder,我无法转换 @符号。
这是我的代码:
byte[] byteFinal ={97, 98, 0, 99, 100};
char ch;
StringBuilder str = new StringBuilder();
for(byte b : byteFinal){
ch = (char)b;
System.out.println("ch:"+ch);
str.append(ch);
}
System.out.println(str.toString());
Run Code Online (Sandbox Code Playgroud)