有没有办法获取 std:string 的缓冲区
有没有办法获取 std::string 的“原始”缓冲区?
我正在考虑类似于 CString::GetBuffer() 的东西。例如,对于 CString 我会这样做:
CString myPath;
::GetCurrentDirectory(MAX_PATH+1, myPath.GetBuffer(MAX_PATH));
myPath.ReleaseBuffer();
那么,std::string 有类似的东西吗?
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:
CString myPath;
::GetCurrentDirectory(MAX_PATH+1, myPath.GetBuffer(MAX_PATH));
myPath.ReleaseBuffer();
So, does std::string have something similar?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
虽然有点不正统,但使用 std::string 作为线性内存缓冲区是完全有效的,唯一需要注意的是,直到 C++11 之前,标准才支持它。
引用草本萨特,
“可能” 是这里的关键。因此,虽然这不是保证,但您应该能够依赖 std::string 是线性内存缓冲区的原则,并且您应该在测试套件中断言有关此的事实,只是为了确保。
您始终可以构建自己的缓冲区类,但是当您想要购买时,这就是 STL 所提供的。
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.To quote Herb Sutter,
"Probably" 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.You can always build your own buffer class but when you're looking to buy, this is what the STL has to offer.
如果您想要一个真正的缓冲区,请使用 std::vector。
Ideone 示例。
Use
std::vector<char>
if you want a real buffer.Example on Ideone.
不方便携带,不。该标准不保证 std::string 在内存中具有唯一的线性表示(并且使用旧的 C++03 标准,甚至允许像绳索这样的数据结构),因此 API 确实不让您访问它。它们必须能够将其内部表示更改为该表示(在 C++03 中)或允许访问其线性表示(如果有的话,这是在 C++11 中强制执行的),但仅限于读取。您可以使用
data()
和/或c_str()
访问它。因此,该接口仍然支持写时复制。使用通过指针访问来修改数组的 C-API 时,通常建议使用
std::vector
,它保证具有恰好用于此目的的线性内存表示。总而言之:如果您想以可移植的方式执行此操作,并且希望字符串以
std::string
结尾,则别无选择,只能将结果复制到字符串中。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 usingdata()
and/orc_str()
. Because of that, the interface still supports copy-on-write.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.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.根据这篇 MSDN 文章,我认为这是直接使用 std::wstring 执行操作的最佳方法。第二好的是 std::unique_ptr,第三好的是使用
std::vector
。请随意阅读这篇文章并得出您自己的结论。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 usingstd::vector<wchar_t>
. Feel free to read the article and draw you own conclusions.它有
c_str
,在我知道的所有 C++ 实现上,它返回底层缓冲区(但作为const char *
,所以你不能修改它)。It has
c_str
, which on all C++ implementations that I know returns the underlying buffer (but as aconst char *
, so you can't modify it).请记住,当 str 被重新分配或超出范围时,sz 将失效。您可以执行类似以下操作来与字符串解耦:
或者,采用老式 C 风格(请注意,这不允许字符串嵌入空字符):
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:
Or, in oldfashioned C style (note that this will not allow strings with embedded null-characters):
我认为你这样做会被性传播疾病崇拜的纯粹主义者所皱眉。无论如何,如果您想要动态字符串类型可以轻松传递给低级 API 函数,这些函数将同时修改其缓冲区和大小,而不需要任何转换,那么最好不要依赖臃肿和通用的标准库。将不得不执行它!这实际上是非常具有挑战性和有趣的任务。例如,在我的自定义
txt
类型中,我重载了此运算符:并且还进行了强制转换:
因此,我可以将
txt
类型直接传递给低级 API 函数,甚至无需调用任何.c_str()
。然后,我还可以向 API 函数传递它的真实大小(即缓冲区的大小)以及指向内部大小变量(operator*()
)的指针,以便 API 函数可以更新写入的字符量,从而给出有效的字符串,根本不需要调用stringlength
!我试图用这个 txt 来模仿基本类型,所以它根本没有公共函数,所有公共接口都只能通过运算符来实现。这样我的
txt
就可以完美地适应int
和其他基本类型。I think you will be frowned upon by the purists of STD cult for doing this. In any case, its much better to not relay on bloated and generic standard library if you want dynamic string type that can be easily passed to low level API functions that will modify its buffer and size at the same time, without any conversions, than you will have to implement it! Its actually very challenging and interesting task to do. For example in my custom
txt
type I overload this operators:And also this casts:
And as such, i can pass
txt
type to low level API functions directly, without even calling any.c_str()
. I can then also pass the API function it's true size (i.e. size of buffer) and also pointer to internal size variable (operator*()
), so that API function can update amount of characters written, thus giving valid string without the need to callstringlength
at all!I tried to mimic basic types with this
txt
, so it has no public functions at all, all public interface is only via operators. This way mytxt
fits perfectly withint
s and other fundamental types.