有没有办法让“原始”缓冲区成为std :: string?
我在考虑与CString::GetBuffer()
类似的东西。例如,使用CString我会这样做:
CString myPath;
::GetCurrentDirectory(MAX_PATH+1, myPath.GetBuffer(MAX_PATH));
myPath.ReleaseBuffer();
那么,std :: string有类似的东西吗?
答案 0 :(得分:16)
如果你想要一个真正的缓冲区,请使用std::vector<char>
。
#include <vector>
#include <string>
int main(){
std::vector<char> buff(MAX_PATH+1);
::GetCurrentDirectory(MAX_PATH+1, &buff[0]);
std::string path(buff.begin(), buff.end());
}
答案 1 :(得分:15)
虽然有点非正统,但使用std::string
作为线性内存缓冲区是完全有效的,唯一需要注意的是,在C ++ 11之前标准不支持它。
std::string s;
char* s_ptr = &s[0]; // get at the buffer
引用Herb Sutter,
我知道的每个std :: string实现实际上是连续的,并且null终止其缓冲区。所以,虽然它不是正式的 保证,在实践中你可以通过调用&amp; str [0]逃脱 获取指向连续且以null结尾的字符串的指针。 (但是 安全,你仍然应该使用str.c_str()。)
可能是关键。因此,虽然它不是保证,但您应该能够依赖std::string
是线性内存缓冲区的原则,并且您应该在测试套件中断言相关事实,以确保。
你可以随时建立自己的缓冲类,但是当你想购买时,这就是STL所提供的。
答案 2 :(得分:3)
不便携,没有。该标准不保证std::string
在内存中具有独占的线性表示(并且使用旧的C ++ 03标准,甚至允许使用绳索等数据结构),因此API不允许您访问它。他们必须能够将其内部表示更改为(在C ++ 03中)或者允许访问它们的线性表示(如果它们有一个,这在C ++ 11中强制执行),但仅用于读取。您可以使用data()
和/或c_str()
来访问此内容。因此,该接口仍然支持写时复制。
使用通过指针访问来修改数组的C-API的通常建议是使用std::vector
,保证为此目的具有线性内存表示。
总结一下:如果你想要便携地这样做,如果你想让你的字符串以std::string
结尾,你别无选择,只能将结果复制到字符串中。
答案 3 :(得分:1)
它有c_str
,在我知道的所有C ++实现上都会返回底层缓冲区(但是作为const char *
,所以你不能修改它。)
答案 4 :(得分:1)
According to this MSDN article,我认为这是直接使用std :: wstring 的最佳方法。第二好的是std::unique_ptr<wchar_t[]>
,第三好的是使用std::vector<wchar_t>
。随意阅读文章并得出自己的结论。
// Get the length of the text string
// (Note: +1 to consider the terminating NUL)
const int bufferLength = ::GetWindowTextLength(hWnd) + 1;
// Allocate string of proper size
std::wstring text;
text.resize(bufferLength);
// Get the text of the specified control
// Note that the address of the internal string buffer
// can be obtained with the &text[0] syntax
::GetWindowText(hWnd, &text[0], bufferLength);
// Resize down the string to avoid bogus double-NUL-terminated strings
text.resize(bufferLength - 1);
答案 5 :(得分:0)
std::string str("Hello world");
LPCSTR sz = str.c_str();
请记住,当str重新分配或超出范围时,sz将失效。你可以做这样的事情从字符串中解耦:
std::vector<char> buf(str.begin(), str.end()); // not null terminated
buf.push_back(0); // null terminated
或者,在旧式C风格中(请注意,这不允许带有嵌入空字符的字符串):
#include <cstring>
char* sz = strdup(str.c_str());
// ... use sz
free(sz);