C++ 有没有办法获得 std:string 的缓冲区
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7836863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to get std:string's buffer
提问by MikMik
Is there a way to get the "raw" buffer o a std::string?
I'm thinking of something similar to CString::GetBuffer()
. For example, with CString I would do:
有没有办法获得“原始”缓冲区 oa std::string?
我在想类似的东西CString::GetBuffer()
。例如,使用 CString 我会这样做:
CString myPath;
::GetCurrentDirectory(MAX_PATH+1, myPath.GetBuffer(MAX_PATH));
myPath.ReleaseBuffer();
So, does std::string have something similar?
那么, std::string 是否有类似的东西?
回答by Xeo
Use std::vector<char>
if you want a real buffer.
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());
}
回答by John Leidegren
While a bit unorthodox, it's perfectly valid to use std::string
as a linear memory buffer, the only caveat is that it isn't supported by the standard until C++11 that is.
虽然有点非正统,但std::string
用作线性内存缓冲区是完全有效的,唯一需要注意的是,直到 C++11 标准才支持它。
std::string s;
char* s_ptr = &s[0]; // get at the buffer
To quote Herb Sutter,
引用赫伯·萨特的话,
Every std::string implementation I know of is in fact contiguous and null-terminates its buffer. So, although it isn't formally guaranteed, in practice you can probably get away with calling &str[0] to get a pointer to a contiguous and null-terminated string. (But to be safe, you should still use str.c_str().)
我知道的每个 std::string 实现实际上都是连续的并且以空值终止其缓冲区。因此,虽然没有正式保证,但实际上您可以通过调用 &str[0] 来获得指向连续且以空字符结尾的字符串的指针。(但为了安全起见,您仍然应该使用 str.c_str()。)
Probable is key here. So, while it's not a guarantee, you should be able to rely on the principle that std::string
is a linear memory buffer and you should assert facts about this in your test suite, just to be sure.
可能是这里的关键。因此,虽然这不是保证,但您应该能够依赖std::string
线性内存缓冲区的原理,并且您应该在测试套件中断言有关这一点的事实,只是为了确定。
You can always build your own buffer class but when you're looking to buy, this is what the STL has to offer.
您始终可以构建自己的缓冲区类,但是当您要购买时,这就是 STL 必须提供的。
回答by ltjax
Not portably, no. The standard does not guarantee that std::string
s have an exclusive linear representation in memory (and with the old C++03 standard, even data-structures like ropes are permitted), so the API does not give you access to it. They must be able to change their internal representation to that (in C++03) or give access to their linear representation (if they have one, which is enforced in C++11), but only for reading. You can access this using data()
and/or c_str()
. Because of that, the interface still supports copy-on-write.
不便携,不。该标准不保证std::string
s 在内存中具有唯一的线性表示(并且在旧的 C++03 标准中,甚至允许使用像绳索这样的数据结构),因此 API 不允许您访问它。他们必须能够将其内部表示更改为(在 C++03 中)或访问其线性表示(如果他们有一个,这在 C++11 中强制执行),但只能用于读取。您可以使用data()
和/或访问它c_str()
。因此,该接口仍然支持写时复制。
The usual recommendation for working with C-APIs that modify arrays by accessing through pointers is to use an std::vector
, which is guaranteed to have a linear memory-representation exactly for this purpose.
使用通过指针访问来修改数组的 C-API 的通常建议是使用std::vector
,它保证具有完全用于此目的的线性内存表示。
To sum this up: if you want to do this portably and if you want your string to end up in an std::string
, you have no choice but to copy the result into the string.
总结一下:如果您想以可移植的方式执行此操作,并且希望您的字符串以 an 结尾std::string
,您别无选择,只能将结果复制到字符串中。
回答by sehe
std::string str("Hello world");
LPCSTR sz = str.c_str();
Keep in mind that sz will be invalidated when str is reallocated or goes out of scope. You could do something like this to decouple from the string:
请记住,当 str 重新分配或超出范围时, sz 将失效。你可以做这样的事情来与字符串解耦:
std::vector<char> buf(str.begin(), str.end()); // not null terminated
buf.push_back(0); // null terminated
Or, in oldfashioned C style (note that this will not allow strings with embedded null-characters):
或者,在老式的 C 风格中(请注意,这将不允许带有嵌入空字符的字符串):
#include <cstring>
char* sz = strdup(str.c_str());
// ... use sz
free(sz);
回答by Fred Foo
It has c_str
, which on all C++ implementations that I know returns the underlying buffer (but as a const char *
, so you can't modify it).
它有c_str
, 在我知道的所有 C++ 实现中都返回底层缓冲区(但作为const char *
,所以你不能修改它)。
回答by sam msft
According to this MSDN article, I think this is the best approach for what you want to do using std::wstring directly. Second best is std::unique_ptr<wchar_t[]>
and third best is using std::vector<wchar_t>
. Feel free to read the article and draw you own conclusions.
根据这篇 MSDN 文章,我认为这是您想要直接使用 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);