2016-08-21 2 views
3

Я получаю программирование ржавчины, чтобы реализовать небольшую программу, и я немного потерялся в преобразовании строк.Преобразование a Vec <u16> или Vec <WCHAR> в a & str

В моей программе, у меня есть вектор следующим образом:

let mut name: Vec<winnt::WCHAR> = Vec::new(); 

WCHAR такая же, как u16 на моей машине Windows.

Передаю Vec<u16> функции C (как указатель), которая заполняет ее данными. Затем мне нужно преобразовать строку, содержащуюся в векторе, в &str. Однако, независимо от того, что я пытаюсь, я не могу заставить это преобразование работать.

Единственное, что мне удалось получить работу, чтобы преобразовать его в WideString:

widestr = unsafe { WideCString::from_ptr_str(name.as_ptr()) }; 

Но это, кажется, шаг в неправильном направлении.

Каков наилучший способ преобразования Vec<u16> в &str в предположении, что вектор содержит допустимую строку с нулевым символом.

ответ

8

Затем мне нужно преобразовать строку, содержащуюся в векторе, в &str. Однако, независимо от того, что я пытаюсь, я не могу заставить это преобразование работать.

Невозможно сделать это «бесплатным» преобразованием.

A &str - строка в Юникоде, закодированная в UTF-8. Это байтовое кодирование. Если у вас есть UTF-16 (или разные, но общая кодировка UCS-2), нет возможности читать один как другой. Это эквивалентно попытке чтения изображения JPEG в формате PDF. Оба фрагмента данных могут быть строкой, но кодировка важна.

Первый вопрос: «Вам действительно нужно это делать?». Много раз вы можете брать данные из одной функции и перетаскивать ее обратно в другую функцию, никогда не глядя на нее. Если вам это удастся, это может быть лучшим ответом.

Если вам необходимо преобразовать его, то вам придется иметь дело с ошибками, которые могут возникнуть. Произвольный массив из 16-разрядных целых чисел может не соответствовать UTF-16 или UCS-2. Эти кодировки имеют краевые случаи, которые могут легко создавать недопустимые строки. Null-завершение - еще один аспект - Unicode фактически позволяет внедрять NUL-символы, поэтому строка с нулевым завершением не может содержать все возможные символы Unicode!

Как только вы убедитесь, что кодировка действительна и выяснил, сколько записей во входном векторе содержит строку, тогда вам необходимо декодировать формат ввода и перекодировать в выходной формат. Вероятно, это потребует какого-то нового распределения, поэтому вы, скорее всего, получите String, который затем можно использовать в любом месте, где можно использовать &str.

Существует встроенный способ преобразования данных UTF-16 в строку: String::from_utf16. Обратите внимание, что он возвращает Result, чтобы разрешить эти ошибки.Также есть String::from_utf16_lossy, который заменяет неверные кодированные части символом замены Unicode.

Если вы начинаете с указателя на u16 или WCHAR, вам нужно будет сначала преобразовать его в срез, используя slice::from_raw_parts. Если у вас есть строка с нулевым завершением, вам нужно найти нужный номер NUL и отрезать вход соответствующим образом.

1: На самом деле это отличный способ использования типов; a &str - , гарантированный, кодированный UTF-8, поэтому дальнейшая проверка не требуется. Аналогично, WideCString, скорее всего, выполнит проверку один раз при построении, а затем может пропустить проверку позже.

+1

Огромное спасибо за то, что вы помогли мне, я был явно потерян и почему-то предполагал, что кодировка обоих типов будет одинаковой. В этом контексте имеет смысл использовать другой объект String (они на самом деле называются объектами в ржавчине?) Для этого преобразования, – Norbert

+2

@Norbert: Я не уверен, что рустеки задумаются о том, называть ли вещи предметы или нет; все просто понимают этот термин, поэтому он достаточно хорош :) –

+0

@Norbert да, я думаю, это зависит от того, что вы хотите назвать «объектом». Если вы имеете в виду кусок данных и связанных с ними методов, то да, это объект. Я думаю, что обычно я просто говорю «тип» вместо «класс», а затем просто «экземпляр типа». Мне не приходилось часто говорить «объект». Я думаю, что все поймут, что ты в порядке. – Shepmaster

Смежные вопросы