2011-12-06 48 views
7

Tôi có một tiêu chuẩn :: vectơ byte (char), tôi muốn thực hiện tương đương với chỉ "Truyền kiểu C" vectơ này thành véc tơ thuộc loại wchar_t. Rõ ràng, những gì tôi thực sự phải làm là để sao chép dữ liệu, nhưng điều ở đây là tôi đã có một dòng byte UTF-16 ở phía bên trái, tôi chỉ muốn di chuyển nó qua các vector wchar_t sao cho Tôi có thể sử dụng nó. Lý tưởng nhất, tôi muốn chỉ trao đổi bộ đệm, nhưng tôi không chắc chắn cách thực hiện điều đó một cách an toàn ...Cách "truyền" một tiêu chuẩn :: vector <char> tới tiêu chuẩn :: vector <wchar_t>

Cách C++ hoạt động sao chép an toàn hiệu quả như thế nào?

LƯU Ý:

tôi làm lưu trữ UTF-16 dây của tôi như std::wstring hoặc std::vector<wchar_t> nhưng tôi có bộ nhớ đệm này mà tôi xảy ra cho biết là UTF-16, và tôi cần phải sao chép nó, bằng cách nào đó ...

+2

gì? Bạn có dữ liệu UTF-16 được lưu trữ dưới dạng 'char'? Btw. chuyển đổi từ 'char' thành' wchar_t' được thực hiện bằng cách sử dụng 'widen', nhưng tôi đoán, đó không phải là những gì bạn muốn http://www.cplusplus.com/reference/std/locale/ctype/widen/ –

+0

http://www.codeproject.com/Tips/196097/Converting-ANSI-to-Unicode-and-back?display=Print có thể trả lời nó –

+0

Và để mở rộng nhận xét của Let_Me_Be: Tại sao bạn có dữ liệu UTF-16 được lưu trữ dưới dạng 'char'? – Griwes

Trả lời

9

Cách hiệu quả nhất (và an toàn nhất) để làm điều đó là không thực hiện. Hãy để số vector<char> của bạn sở hữu bộ đệm dữ liệu và chỉ cần tạo một cặp gồm wchar_t con trỏ để sử dụng làm trình vòng lặp trỏ vào vectơ.

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

Bây giờ bạn có một cặp lặp sẽ hoạt động tốt với tất cả các thuật toán thư viện chuẩn. Và bạn không phải sao chép một byte. :)

(Disclaimer: Tôi giả định rằng kích thước của vector là chia hết cho sizeof(wchar_t) Nếu không, bạn sẽ phải điều chỉnh con trỏ last.)

+1

+1 cho sự tỉnh táo và đơn giản – johnathon

+0

Điều đó đã chết, và sau đó tôi có thể sử dụng chỉ định và điều đó sẽ sao chép nội dung, đúng không? Nó là tốt để sao chép nó trong tâm trí của tôi, tôi đã chỉ hy vọng cho một trick trao đổi. Tôi có nghĩa là, các internals của một std :: vector là như nhau, tôi chỉ muốn trao đổi ra các innards (như một 'reinterpret_cast'), nhưng điều này sẽ làm độc đáo. –

+0

'static_cast' sẽ hoạt động tốt. –

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); 

Tôi chưa thử nghiệm điều này, nhưng tôi không thể tưởng tượng rằng một cái gì đó như thế này sẽ không hoạt động ... Nếu bạn có vấn đề về cuối, điều này sẽ trở nên phức tạp hơn một chút.

+0

Sử dụng '& v2.back() + 1' thay vì' end() ', vì' end() 'trả về một trình lặp. Nhầm lẫn, nó có thể xuất hiện để làm việc kể từ khi iterator xảy ra là một con trỏ, và sau đó ngừng làm việc sau này (trên thực hiện khác hoặc với một phiên bản gỡ lỗi 'vector'). –

+0

@SteveJessop: Đó là một điểm rất tốt. Cảm ơn. –

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)); 
Các vấn đề liên quan