C++中的const-correctness仍让我感到头疼.在使用一些旧的C代码时,我发现自己需要将C++字符串对象转换为C字符串并将其分配给变量.但是,变量是a char *
并c_str()
返回a const char []
.有没有一个很好的方法来解决这个问题,而不必自己动手去做呢?
编辑:我也试图避免调用新的.我很乐意交易稍微复杂的代码,以减少内存泄漏.
sbi*_*sbi 24
因为对于我莫名的原因,没有人回答了这个我现在做的方式,因为其他的问题现在正在封闭指向这一个,在这里我要补充这一点,即使一年即将到来太晚将意味着它挂在最堆的底部......
使用C++ 03时,std::string
不保证将其字符存储在连续的内存中,并且结果c_str()
不需要指向字符串的内部缓冲区,因此保证工作的唯一方法是:
std::vector<char> buffer(s.begin(), s.end());
foo(&buffer[0], buffer.size());
s.assign(buffer.begin(), buffer.end());
Run Code Online (Sandbox Code Playgroud)
由于没有已知的实现,实际上使用的非连续的内存,由于std::string
使用了被许多人认为,如果这是有保证的,规则将被改变为即将到来的标准,现在保证其字符连续内存.所以在C++ 1x中,这应该工作:
foo(&s[0], s.size());
Run Code Online (Sandbox Code Playgroud)
但是,这需要注意:在调用任何可能更改字符串的成员函数之前,&s[0]
(仅作为s.c_str()
BTW的结果)的结果才能保证有效.所以你不应该把这些操作的结果存储在任何地方.正如我的例子所做的那样,最安全的是在完整表达结束时完成它们.
dmc*_*kee 12
我想总有strcpy
.
或者char*
在C++代码中必须与旧东西接口的部分使用字符串.
或者重构现有代码以使用C++编译器进行编译然后使用std:string
.
Joe*_*bel 12
你需要在这里做一个重要的区别:char*
你希望指定这个"道德常数"吗?就是说,抛弃const
- 只是一种技术性,你真的仍然会把字符串视为一个const
?在这种情况下,您可以使用强制转换 - 无论是C风格还是C++风格const_cast
.只要你(和其他人谁以往任何时候都维持这个代码)有纪律来治疗char*
的const char*
,你会没事的,但是编译器将不再看着你回来,所以如果你把它作为一个非const
您可能正在修改代码中其他内容依赖的缓冲区.
如果您char*
将被视为非const
,并且您打算修改它指向的内容,则必须复制返回的字符串,而不是丢弃其const
-ness.
mch*_*mch 10
const -cast总是......
std::string s("hello world");
char *p = const_cast<char *>(s.c_str());
Run Code Online (Sandbox Code Playgroud)
当然,这基本上颠覆了类型系统,但有时在与旧代码集成时是必要的.
您可以使用复制方法:
len = myStr.copy(cStr, myStr.length());
cStr[len] = '\0';
Run Code Online (Sandbox Code Playgroud)
哪里myStr
是你的C++字符串和cStr
一个char *
至少myStr.length()
+1大小.此外,len
是类型size_t
和需要,因为副本不会终止cStr
.
如果您可以负担得起额外的分配,那么建议您strcpy
考虑使用以下替代建议的方法std::vector<char>
:
// suppose you have your string:
std::string some_string("hello world");
// you can make a vector from it like this:
std::vector<char> some_buffer(some_string.begin(), some_string.end());
// suppose your C function is declared like this:
// some_c_function(char *buffer);
// you can just pass this vector to it like this:
some_c_function(&some_buffer[0]);
// if that function wants a buffer size as well,
// just give it some_buffer.size()
Run Code Online (Sandbox Code Playgroud)
对我来说,这比C ++更像是一种C ++方式strcpy
。看看Meyers的有效STL项目16,可以得到比我所能提供的更好的解释。
只需使用 const_cast<char*>(str.data())
不要为此感到难过或奇怪,这样做是非常好的风格。
它保证在 C++11 中工作。它完全是 const 限定的这一事实可以说是它之前的原始标准的错误;在 C++03 中,可以实现string
为不连续的内存列表,但从来没有人这样做过。string
除了连续的内存块之外,地球上没有任何编译器可以实现,因此请放心地将其视为这样。