2014-01-05 7 views
0

Я пишу класс шаблона String (только для учебных целей) и имею небольшую проблему. Если T - wchar_t и U - char, и наоборот, что мне не хватает для этого метода?Преобразование из wchar_t a char и наоборот

template<typename U> 
String<T> operator + (const U* other) 
{ 
    String<T> newString; 
    uint32_t otherLength = length(other); 
    uint32_t stringLength = m_length + otherLength; 
    uint32_t totalLength = stringLength * sizeof(T) + sizeof(T); 

    T *buffer = new T[totalLength]; 

    memset(buffer, 0, totalLength); 
    memcpy(buffer, m_value, m_length * sizeof(T)); 
    newString.m_value = buffer; 
    newString.m_length = stringLength; 
    memcpy(newString.m_value + m_length, other, otherLength * sizeof(T)); 

    return newString; 
} 

Хорошо, Джаред ниже предложил решение, так что-то вроде этого (есть ошибки, я знаю, просто шаблон)?

template<typename U> 
String<T> operator + (const U* other) 
{ 
    String<T> newString; 

    uint32_t sizeOfT = sizeof(T); // wchar_t is 4 
    uint32_t sizeOfU = sizeof(U); // char is 1 

    T* convertedString; 

    int i = 0; 
    while (*other != 0) 
    { 
     convertedString[i] = ConvertChar(*other); 
     other++; 
     i++; 
    } 

    return newString; 
} 

template <typename U> 
T ConvertChar(U character) 
{ 

} 
+0

Если все ваши персонажи ASCII, то немой wchar_t на char хорошо. в любом другом случае вам нужно преобразовать Unicode в UTF8. http://utfcpp.sourceforge.net/ – SHR

ответ

1

Сейчас ваш код в основном с использованием копий памяти при преобразовании из U* в String<T>. К сожалению, это не сработает, потому что у wchar_t и char есть разные макеты памяти. В частности, wchar_t обычно занимает 2 байта, а char - это один byte. Что вам нужно установить здесь собственная функция преобразования, которая должна быть применена к каждому элементу в строке

T ConvertChar(U c) { ... } 
+0

Правда. Кроме того, wchar_t <-> преобразование символов - это не только усечение/расширение каждого элемента. Это так, если ваш язык - английский, и вы используете только wchar_t в интервале [0, 256). –

+0

Эй, Джаред. Я редактировал свой первый пост, что-то вроде этого? – Thunder

+0

@ Fallen да, это близко к тому, что я ожидаю. Но теперь вам нужно интегрировать это в цикл. Вместо «memcpy» вам нужно применить это преобразование к каждому символу в исходной строке. – JaredPar

1

В то время как вы могли бы просто расширить при переходе от char к wchar_t (т.е. использовать wchar_t(c)), но это, вероятно, делает неправильная вещь. При преобразовании с wchar_t в char очевидно, что вы, вероятно, потеряете информацию. Общепринято, что индивидуальные символы на самом деле делают не представляют собой отдельные символы, но на самом деле представляют собой просто байты, представляющие UTF-8 или UTF-16. В этом случае элементы, вероятно, должны быть закодированы/декодированы в соответствующее другое представление. Очевидно, что преобразование не один к одному: некоторые символы Unicode состоят из нескольких байтов UTF-8 и нескольких слов UTF-16.

Возможно, вы захотите взглянуть на std::codecvt<...> для преобразования кодировок.

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