有没有办法获得std:string buffer

时间:2011-10-20 13:44:10

标签: c++ winapi stl stdstring

有没有办法让“原始”缓冲区成为std :: string?
我在考虑与CString::GetBuffer()类似的东西。例如,使用CString我会这样做:

CString myPath;  
::GetCurrentDirectory(MAX_PATH+1, myPath.GetBuffer(MAX_PATH));  
myPath.ReleaseBuffer();  

那么,std :: string有类似的东西吗?

6 个答案:

答案 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());
}

Example on Ideone

答案 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);