c++ - 预分配 std::string 以传递到 WinAPI

标签 c++ windows winapi std stdstring

我很好奇下面的代码是否正确?我在较旧版本的 VS 2008 上运行它,用于仅 Windows 的 C++ 项目。

我的目标是在 std::string 中预分配内存,以将其传递到 WinAPI 中,并了解所需的字符大小:

//'hWnd' = window handle
int nLn = GetWindowTextLength(hWnd);

//Text variable to collect text in
std::wstring str;
str.reserve(nLn);

GetWindowText(hWnd, (LPTSTR)str.data(), nLn);

我担心的是 str.data() 返回 const wchar_t *GetWindowText() 请求 LPTSTR >,这不是一个 const 缓冲区。那里可以进行类型转换吗?

最佳答案

我不能代表 VS2008,但大多数 C++11 之前版本都遵循 &str[0] + i == str.data() + i 的 C++11 规则,所以&str[0]有效并且不需要任何强制转换1,这是比破坏类型系统和标准更安全的途径。请小心,因为您不允许覆盖字符串后面的空终止符,即使使用另一个空终止符也是如此。如果您无法在 VS2008 中保证这一点,那么 std::vector<wchar_t>将是首选解决方案。

但是,您还有另一个问题。 reserve并不能阻止访问 str 的未定义行为出界。界限基于 size() ,不是capacity() 。您需要更改reserveresize .

即便如此,你还有另一个问题。 GetWindowTextLength不包括空终止符。您必须使用nLn + 1在该调用后面的代码中。

进行更改后,这将适用于任何符合 C++11 的实现,包括一些 C++11 之前的实现,并忽略错误检查:

int nLnWithNul = GetWindowTextLength(hWnd);

std::wstring str(nLnWithNul, '\0'); // bit of a shorthand for the resize call
int nCopiedLn = GetWindowText(hWnd, &str[0], nLnWithNul);
str.resize(nCopiedLn);

最后resize调用处理短于 nLnWithNul 的复制标题。例如,如果标题从 GetWindowTextLength 开始缩小被称为。调整大小后,字符串将仅包含复制的文本,后面不包含任何 NUL 字符。


1:参见my previous question的答案.

关于c++ - 预分配 std::string 以传递到 WinAPI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34302563/

相关文章:

windows - 在批处理文件中获取 Windows 版本

c++ - 带有 RRF_RT_REG_SZ 的 RegSetValueEx 在注册表中生成 REG_EXPAND_SZ?

c++ - 如何将文本更改为语音以及如何将字符插入字符数组

c++ - 查找 vector 是否为子 vector C++

c++ - C 或 C++ 编写编译器?

c++ - 从自定义分配器调用 deallocate 抛出无法解释的异常

windows - 未记录的控制台输入模式标志

c++ - 如何强制编译器选择特定的函数特化

java - 使用 URL 将图片加载到圈子中的 JavaFX 在 Windows 上出错

winapi - 用于搜索的通用 LDAP 库?