2011-12-06 18 views
7

Tengo un std :: vector de bytes (char), me gustaría hacer el equivalente de "casting de estilo C" solo este vector a un vector que es del tipo wchar_t.Cómo "fundido" un std :: vector <char> std :: vector <wchar_t>

Obviamente, lo que realmente tengo que hacer es copiar los datos, pero el asunto aquí es que ya tengo un flujo de bytes UTF-16 en el lado izquierdo, solo quiero moverlo al vector wchar_t para que Puedo utilizarlo. Idealmente, me gustaría simplemente cambiar el búfer, pero no estoy seguro de cómo hacerlo de manera segura ...

¿Cuál es la forma C++ de hacer una operación de copiado de conversión tan eficiente como segura?

NOTA:

almaceno mis cadenas UTF-16 como std::wstring o std::vector<wchar_t> pero tengo este búfer de memoria que resulta que sé es UTF-16, y tengo que copiarlo, de alguna manera ...

+2

¿Qué? ¿Tiene datos UTF-16 almacenados como 'char'? Por cierto. la conversión de 'char' a' wchar_t' se hace usando 'widen', pero supongo que eso no es lo que quiere http://www.cplusplus.com/reference/std/locale/ctype/widen/ –

+0

http://www.codeproject.com/Tips/196097/Converting-ANSI-to-Unicode-and-back?display=Print puede responderlo –

+0

Y para extender el comentario de Let_Me_Be: ¿Por qué tiene datos UTF-16 almacenados como 'char'? – Griwes

Respuesta

9

La forma más eficiente (y más segura) de hacerlo es no hacerlo. Deje que su vector<char> tenga el búfer de datos, y simplemente cree un par de punteros wchar_t para usar como iteradores que apuntan al vector.

std::vector<char> vec; 
wchar_t* first = reinterpret_cast<wchar_t*>(&vec[0]); 
wchar_t* last = reinterpret_cast<wchar_t*>(&vec[0] + vec.size()); 

Ahora usted tienen un par de iterador que va a trabajar muy bien con todos los algoritmos de la biblioteca estándar. Y no tiene que copiar un solo byte. :)

(Negación: Estoy asumiendo que el tamaño del vector es divisible por sizeof(wchar_t) De lo contrario, tendrá que ajustar el puntero last.)

+1

+1 por cordura y simplicidad – johnathon

+0

Eso está muerto, y luego solo puedo usar Asignar y eso copiará las cosas, ¿verdad? Está bien copiarlo en mi mente, solo esperaba un truco de intercambio. Quiero decir, las partes internas de un std :: vector son las mismas, solo quiero intercambiar las tripas (como un 'reinterpret_cast'), pero esto funcionará muy bien. –

+0

'static_cast' haría muy bien. –

1
std::vector<char> v1; 
std::vector<wchar_t> v2; 

wchar_t *begin = (wchar_t *) &v2.front(); 
wchar_t *end = (wchar_t *) (&v2.back() + 1); 

v1.assign(begin, end); 

No he probado esto, pero no puedo imaginar que algo así no funcione ... Si tienes problemas endian, esto sería un poco más complicado.

+0

Use '& v2.back() + 1' en lugar de' end() ', ya que' end() 'devuelve un iterador. Confusamente, puede parecer que funciona, ya que el iterador es un puntero y luego deja de funcionar más tarde (en otra implementación o con una versión de depuración de 'vector'). –

+0

@SteveJessop: Ese es un muy buen punto. Gracias. –

1
std::vector<char> v1; 
std::vector<wchar_t> v2; 

const char * cv1 = v1.data(); 

const wchar_t * cv2 = static_cast<const wchar_t *>(cv1); 
std::copy(cv2, cv2 + v1.size()/sizeof(wchar_t), std::back_inserter(v2)); 
Cuestiones relacionadas