Альтернативное чтение как char* и wchar_t*

Я пытаюсь написать программу, которая анализирует теги ID3 для образовательных целей (поэтому, пожалуйста, объясните подробно, как я пытаюсь научиться). До сих пор я имел большой успех, но застрял в проблеме кодирования.

При чтении mp3-файла кодировка по умолчанию для всего текста - ISO-8859-1. Вся информация заголовка (идентификаторы кадров и т. Д.) Может быть прочитана в этой кодировке.

Вот как я это сделал:

ifstream mp3File("../myfile.mp3");
mp3File.read(mp3Header, 10);  // char mp3Header[10];

// .... Parsing the header

// After reading the main header, we get into the individual frames.
// Read the first 10 bytes from buffer, get size and then read data 
char encoding[1]; 
while(1){
    char frameHeader[10] = {0};
    mp3File.read(frameHeader, 10);
    ID3Frame frame(frameHeader);  // Parses frameHeader 
    if (frame.frameId[0] == 'T'){ // Text Information Frame
        mp3File.read(encoding, 1); // Get encoding
        if (encoding[0] == 1){
            // We're dealing with UCS-2 encoded Unicode with BOM
            char data[frame.size];
            mp3File.read(data, frame.size);
        }
    }
}

Это плохой код, потому что data это char*, его внутренняя часть должна выглядеть следующим образом (преобразует неотображаемые символы в int):

char = [0xFF, 0xFE, C, 0, r, 0, a, 0, z, 0, y, 0]

Два вопроса:

  1. Каковы первые два байта? - ответил.
  2. Как я могу прочитать wchar_t из моего уже открытого файла? А потом вернуться к чтению остального?

Уточнение правки: я не уверен, что это правильный способ сделать это, но, по сути, я хотел сделать следующее: прочитать первые 11 байтов в массив символов (заголовок + кодировка), а затем следующие 12 байтов в массив wchar_t (название песни), а затем следующие 10 байтов в массив символов (следующий заголовок). Это возможно?

1 ответ

Я нашел приличное решение: создать новый буфер wchar_t и добавить символы из массива char попарно.

wchar_t* charToWChar(char* cArray, int len) {
    char wideChar[2];
    wchar_t wideCharW;
    wchar_t *wArray = (wchar_t *) malloc(sizeof(wchar_t) * len / 2);
    int counter = 0;
    int endian = BIGENDIAN;

    // Check endianness
    if ((uint8_t) cArray[0] == 255 && (uint8_t) cArray[1] == 254)
        endian = LITTLEENDIAN;
    else if ((uint8_t) cArray[1] == 255 && (uint8_t) cArray[0] == 254)
        endian = BIGENDIAN;

    for (int j = 2; j < len; j+=2){
        switch (endian){
            case LITTLEENDIAN: {wideChar[0] = cArray[j]; wideChar[1] = cArray[j + 1];} break;
            default:
            case BIGENDIAN: {wideChar[1] = cArray[j]; wideChar[0] = cArray[j + 1];} break;
        }

        wideCharW = (uint16_t)((uint8_t)wideChar[1] << 8 | (uint8_t)wideChar[0]);
        wArray[counter] = wideCharW;
        counter++;
    }
    wArray[counter] = '\0';
    return wArray;
}

Использование:

    if (encoding[0] == 1){
        // We're dealing with UCS-2 encoded Unicode with BOM
        char data[frame.size];
        mp3File.read(data, frame.size);
        wcout << charToWChar(data, frame.size) << endl;
    }
Другие вопросы по тегам