在Windows上使用std::copy来复制宽字符串

Using std::copy to copy wide strings on Windows

本文关键字:copy 字符串 复制 std Windows      更新时间:2023-10-16

假设我有一个像这样的宽字符串

std::wstring s(L"Stack Over Flow");
我想使用std::copy

复制到宽字符std::vector<wchar_t> (null终止字符串)的向量中以下两种方法似乎都有效
第一个

std::vector<wchar_t> c( s.size() + 1 );
std::copy(s.c_str(), s.c_str() + s.length() + 1, c.begin());
wprintf( L"%sn",&c[0] );

第二

std::vector<wchar_t> d( s.size() + sizeof(wchar_t));
std::copy(s.c_str(), s.c_str() + s.length() + sizeof(wchar_t), d.begin());
wprintf( L"%sn",&d[0] );

但我认为第一个应该失败,因为我没有为结束null字符分配正确的大小。我错过了什么?
编辑
不,我不想看这个

std::vector<wchar_t> c(s.begin(), s.end()); <br>

,因为我正在调整现有缓冲区的大小
编辑
通过改变用例(使用类似C的API打印),我可以看到第二个版本可能是正确的。首印Stack Over Flow????????
第二次按预期打印Stack Over Flow

为什么这么多大杂烩?

我想知道你为什么不这样做:

std::vector<wchar_t> c(s.begin(), s.end());

简单,简洁!

至于你的代码,两个版本都是错误的。两者都是错误的,因为第二个参数超出了末尾,因为它应该只有s.c_str() + s.length()。也就是说,

2nd arg ---> s.c_str() + s.length() //correct
2nd arg ---> s.c_str() + s.length() + 1 //wrong - first version
2nd arg ---> s.c_str() + s.length() + sizeof(wchar_t) //wrong - second version
如果你遵循简单的代码,习惯的代码,你可以避免很多错误。

如果您使用std::copy,例如,当您由于某种原因不能使用向量构造函数时,那么习惯的std::copy是这样的:

void f(std::vector<wchar_t> & c)
{
  //you cannot use constructor version now, so use std::copy as
  std::copy(s.begin(), s.end(), std::back_inserter(c));
}
编辑:

如果你正在使用C库,以及与C -string一起工作的api,那么我建议你使用std::wstring(或std::string)。我不认为使用std::vector有什么意义,因为它给代码增加了混乱。如果您使用vector,您必须在末尾附加一个空字符,以便使其工作:

  c.push_back(''); //do this after copying!

但是我仍然不认为这样做有任何意义,因为你试图把vector当作字符串来对待。如果你需要字符串,为什么不使用std::wstring,它是std::wstring::c_str()来获得c-string

当您请求std::vector<wchar_t> c(size)时,它会分配足够的空间来包含wchar_t大小的项目-您请求的大小不是以字节为单位,而是以wchar_t项目为单位。

第一:当你有一个大小敏感的容器时,你实际上不需要一个结束null字符。

其次,std::vector<T>的构造函数接受T元素的个数,而不是字节数。所以+1意味着一个额外的wchar_t(0)

[编辑]对于编辑过的问题,最简单的解决方案似乎是c.assign(s.begin(), s.end())