简体   繁体   English

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

[英]Using std::copy to copy wide strings on Windows

Let's say I have a wide string like this 假设我有这样一个宽字符串

std::wstring s(L"Stack Over Flow");

that I want to copy into a vector of wide characters std::vector<wchar_t> (of a null terminated string ) using std::copy 我想使用std::copy复制到宽字符std::vector<wchar_t> (以null结尾的字符串的std::vector<wchar_t>
Both the following approaches seem to work 以下两种方法似乎都有效
First 第一

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

Second 第二

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"%s\n",&d[0] );

But I am thinking the first should fail because I am not allocating the correct size for the ending null character. 但是我认为第一个应该失败,因为我没有为结尾的空字符分配正确的大小。 What did I miss? 我错过了什么?
Edit 编辑
No, I don't want to to this 不,我不想这样

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

because I am resizing an existing buffer 因为我正在调整现有缓冲区的大小
Edit 编辑
By changing the use case (print using the C like API ) I can see that the second version is probably the correct one. 通过更改用例(使用类似C的API进行打印),我可以看到第二个版本可能是正确的版本。
First prints Stack Over Flow???????? 首先打印Stack Over Flow????????
Second prints Stack Over Flow as expected 第二份印刷品按预期Stack Over Flow

Why so much hotchpotch? 为什么这么多辣酱?

I wonder why you're not doing this: 我想知道为什么您不这样做:

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

Simple, and concise! 简单,简洁!

As for your code, both versions are wrong. 至于您的代码,这两个版本都是错误的。 Both are wrong because the second argument is going beyond the end, as it should be only s.c_str() + s.length() . 两者都是错误的,因为第二个参数超出了结尾,因为它只能是s.c_str() + s.length() That is, 那是,

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

If you follow simple code, idiomatic code, you can avoid much of error. 如果遵循简单代码,惯用代码,则可以避免很多错误。


If you use std::copy , for example when you cannot use vector constructor for some reason, then the idiomatic std::copy is this: 如果您使用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));
}

EDIT: 编辑:

If you're working with C library, and APIs which works with c-string, then I would suggest you to use std::wstring (or std::string ). 如果您正在使用C库以及与c-string一起使用的API,那么我建议您使用std::wstring (或std::string )。 I don't see much point in using std::vector , for it adds confusion to the code. 我看不到使用std::vector ,因为它会使代码更加混乱。 If you use vector, you have to append a null character at the end, so as to make it work: 如果使用向量,则必须在末尾添加一个空字符,以使其起作用:

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

But I still don't see any point in doing that, as you're trying to treat vector like a string. 但是我仍然看不到这样做的任何意义,因为您试图将向量视为字符串。 If you need string, why not use std::wstring and it's std::wstring::c_str() to get the c-string. 如果您需要字符串,为什么不使用std::wstring ,它是std::wstring::c_str()来获取c字符串。

当您要求一个std::vector<wchar_t> c(size)它会分配足够的空间来容纳大小为wchar_t项目-您要求的大小不是以字节为单位,而是以wchar_t项的形式。

First: You don't actually need an ending null character, when you have a size-aware container. 第一:当您有一个可识别尺寸的容器时,实际上不需要结尾的空字符。

Secondly, this constructor for std::vector<T> takes the number of T elements, not bytes. 其次,此std::vector<T>构造方法使用T元素的数量,而不是字节。 So +1 means one extra wchar_t(0) . 因此+1表示额外的wchar_t(0)

[edit] With the edited question, the easiest solution seems c.assign(s.begin(), s.end()) . [编辑]对于已编辑的问题,最简单的解决方案似乎是c.assign(s.begin(), s.end())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM