Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.12.2013, 20:08   #21
nikmoon
Форумчанин
 
Регистрация: 13.11.2013
Сообщений: 149
По умолчанию

Отлично )
А то я его только на двух символах К проверил )
nikmoon вне форума Ответить с цитированием
Старый 04.12.2013, 21:05   #22
Realism_32
Пользователь
 
Регистрация: 01.12.2013
Сообщений: 17
По умолчанию

После нескольких часов беспрерывных попыток сделать хоть что-то путное я сдался.
Попытался оформить взятие строки из файла - не выходит.
Оформил тестовое взятие одного символа из файла - переводит только английские в английские. Русские символы вызывают падение программы.
Увеличивал размерность массивов, и выделял для них динамическую память. Бесполезно.
Вот потрепанный под Си код, с попытками файлового ввода-вывода:

Код:
#include <stdio.h>
#include <string.h>


// вторая часть таблицы кодировки для перевода из UNICODE в koi8-r
// первая часть совпадает с ASCII
unsigned int codepage[128] =
{
    0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
    0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248, 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
    0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
    0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
    0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
    0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
    0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
    0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
};


// преобразование последовательности UTF-8 в
// последовательность UNICODE big-endian
// на входе:
//    utf8 - начало UTF-8 последовательности
//    unicode - буфер 6 байт
//    len - не имеет значения
// на выходе:
//    unicode - последовательность unicode
//    len - длина в байтах
void UTF8_to_UNICODE(char *utf8, char *unicode, int *len)
{
    // выясним длину заданного символа utf-8
    if (!(utf8[0] & 0x80))    // старший бит = 0 => длина = 1 байт
    {
        unicode[0] = utf8[0];
        *len = 1;
        return;
    }
    else if (!(utf8[0] & 0x20))    // длина = 2 байт
    {
        unicode[0] = (utf8[0] >> 2) & 0x07;    // первый байт
        unicode[1] = (utf8[1] & 0x3F) | ((utf8[0] << 6) & 0xC0);
        *len = 2;
        return;
    }
    
    return;
}

// преобразование кода UNICODE в код KOI8-R
char UNICODE_to_KOI8R(unsigned int unicode)
{
    if (unicode <= 127)    // код из первой части таблицы
        return unicode;        // возвращаем как есть

    // найдем код из второй части таблицы
    int index = 0;
    while (unicode != codepage[index])
    {
        index++;
    }
    return (0x80 + index);
}



int main(int argc, char* argv [])
{    
    int sim;
    int i=0;
    FILE* f1 = fopen(argv[1], "r");
    FILE* f2 = fopen(argv[2], "w");
    // значения для проверки, UTF-8, 2 кириллических символа 'К'
    unsigned short arr[1000];// = { 0x9AD0, 0x9AD0, 0x0000 };
    
    /*while((sim = fgetc(f1)) !=EOF) // Тестовый цикл, хотя бы
                    //для одного символа из файла
                    //Нужно оформить для взятия строки
                    //Наверняка ошибка в типах данных
                    //При взятии символа кириллицы - Segmentation fault :(
    {
        arr[i] = sim;
        i++;
            
    } */
    char *strUTF8 = (char *)&arr;    // строка в коде UTF-8
    char strKOI8R[20];        // здесь будут храниться перекодированные символы
    char buff[6];            // буфер для символов в UNICODE
    // посимвольно разбираем строку в формате UTF-8
    int utf8_index = 0;
    int koi8r_index = 0;
    while (utf8_index < strlen(strUTF8))
    {
        int len;

        // преобразовываем символ из UTF-8 в UNICODE
        UTF8_to_UNICODE(&strUTF8[utf8_index], buff, &len);

        // теперь из UNICODE в KOI8-R
        if (len == 1)
            strKOI8R[koi8r_index] = buff[0];
        else if (len == 2)
        {
            strKOI8R[koi8r_index] = UNICODE_to_KOI8R((buff[0] << 8) | buff[1]);
        }
        koi8r_index++;        // следующий символ в строке с KOI8-R
        utf8_index += len;    // следующий символ в строке с UTF-8
    }

    strKOI8R[koi8r_index] = '\0';    // устанавливаем признак конца строки
    fprintf(f2,"%s",strKOI8R);
        
    fclose(f2);
    fclose(f1);
    return 0;
}
Realism_32 вне форума Ответить с цитированием
Старый 04.12.2013, 21:23   #23
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

По вашему, когда закончится этот цикл?
Код:
int index = 0;
while (unicode != codepage[index])
{
  index++;
}
Кроме того, я бы отпечатывал код unicode символа на входе - вы уверены, что у вас все коды правильные?
Вычисление unicode[1] тоже сильно подозрительное.

Последний раз редактировалось waleri; 04.12.2013 в 21:26.
waleri вне форума Ответить с цитированием
Старый 04.12.2013, 21:25   #24
nikmoon
Форумчанин
 
Регистрация: 13.11.2013
Сообщений: 149
По умолчанию

Не нужен тебе массив unsigned short, я его создал только лишь, потому что удобно для ручного определения символов UTF-8.
Не читай файл посимвольно, так не сработает.
Определи размер файла в байтах, выдели необходимое количество памяти и тупо считывай ВЕСЬ файл в обычную строку (char[] или char*) и используй эту строку там, где используется strUTF8.
И учти, если в начале файла будет сигнатура, ее надо пропустить.

Последний раз редактировалось nikmoon; 04.12.2013 в 21:32.
nikmoon вне форума Ответить с цитированием
Старый 04.12.2013, 21:26   #25
nikmoon
Форумчанин
 
Регистрация: 13.11.2013
Сообщений: 149
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
По вашему, когда закончится этот цикл?
Код:
int index = 0;
while (unicode != codepage[index])
{
  index++;
}
Цикл закончится, когда unicode будет равно codepage[index].
Цитата:
Кроме того, я бы отпечатывал код unicode символа на входе - вы уверены, что у вас все коды правильные?
Вычисление unicode[1] тоже сильно подозрительное.
Я бы тоже отпечатывал, но пусть ТС хоть отладит сам, если что не так будет.
Мне непонятно, что подозрительного. Кажется может быть или правильно, или неправильно.

Последний раз редактировалось nikmoon; 04.12.2013 в 21:31.
nikmoon вне форума Ответить с цитированием
Старый 06.12.2013, 17:34   #26
Realism_32
Пользователь
 
Регистрация: 01.12.2013
Сообщений: 17
По умолчанию

Отладил, теперь читает файл полностью.
Программа работает без ошибок, декодирует все верно. nikmoon, большое спасибо за помощь Вы очень мне помогли.

Если что, вот код (си) :

Код:
#include <stdio.h>
#include <string.h>
#define SIZE_STR 100 


// вторая часть таблицы кодировки для перевода из UNICODE в koi8-r
// первая часть совпадает с ASCII
unsigned int codepage[128] =
{
    0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
    0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248, 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
    0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
    0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
    0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
    0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
    0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
    0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
};


// преобразование последовательности UTF-8 в
// последовательность UNICODE big-endian
// на входе:
//    utf8 - начало UTF-8 последовательности
//    unicode - буфер 6 байт
//    len - не имеет значения
// на выходе:
//    unicode - последовательность unicode
//    len - длина в байтах
void UTF8_to_UNICODE(char *utf8, char *unicode, int *len)
{
    // выясним длину заданного символа utf-8
    if (!(utf8[0] & 0x80))    // старший бит = 0 => длина = 1 байт
    {
        unicode[0] = utf8[0];
        *len = 1;
        return;
    }
    else if (!(utf8[0] & 0x20))    // длина = 2 байт
    {
        unicode[0] = (utf8[0] >> 2) & 0x07;    // первый байт
        unicode[1] = (utf8[1] & 0x3F) | ((utf8[0] << 6) & 0xC0);
        *len = 2;
        return;
    }
    
    return;
}

// преобразование кода UNICODE в код KOI8-R
char UNICODE_to_KOI8R(unsigned int unicode)
{
    if (unicode <= 127)    // код из первой части таблицы
        return unicode;        // возвращаем как есть

    // найдем код из второй части таблицы
    int index = 0;
    while (unicode != codepage[index])
    {
        index++;
    }
    return (0x80 + index);
}



int main(int argc, char* argv [])
{
    FILE* f1 = fopen(argv[1], "r");
    FILE* f2 = fopen(argv[2], "w");
   
    
    
        char text[SIZE_STR];   // чаровский ящик для хранения символов из f1
        
        while(!feof(f1))          // пока не конец файла, делаем
    {        
    fgets(text,SIZE_STR,f1);      // читаем строку и запоминаем в массив
    

    char *strUTF8 = (char *)&text;    // строка в коде UTF-8
    char strKOI8R[100];        // здесь будут храниться перекодированные символы
    char buff[64];            // буффер для символов в UNICODE
    
    
    // посимвольно разбираем строку в формате UTF-8
    int utf8_index = 0;
    int koi8r_index = 0;
    while (utf8_index < strlen(strUTF8))
    {
        int len;

        // преобразовываем символ из UTF-8 в UNICODE
        UTF8_to_UNICODE(&strUTF8[utf8_index], buff, &len);

        // теперь из UNICODE в KOI8-R
        if (len == 1)
            strKOI8R[koi8r_index] = buff[0];
        else if (len == 2)
        {
            strKOI8R[koi8r_index] = UNICODE_to_KOI8R((buff[0] << 8) | buff[1]);
        }
        koi8r_index++;        // следующий символ в строке с KOI8-R
        utf8_index += len;    // следующий символ в строке с UTF-8
    }

    strKOI8R[koi8r_index] = '\0';    // устанавливаем признак конца строки
        fprintf(f2,"%s",strKOI8R);       // пишем массив в конечный файл
     }
         return 0;
}

Последний раз редактировалось Realism_32; 06.12.2013 в 17:39.
Realism_32 вне форума Ответить с цитированием
Старый 06.12.2013, 20:38   #27
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Цитата:
Сообщение от nikmoon Посмотреть сообщение
Цикл закончится, когда unicode будет равно codepage[index].
Угум, что будет если unicode равно скажем 0x1234? Когда закончится цикл?
waleri вне форума Ответить с цитированием
Старый 07.12.2013, 13:55   #28
Realism_32
Пользователь
 
Регистрация: 01.12.2013
Сообщений: 17
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Угум, что будет если unicode равно скажем 0x1234? Когда закончится цикл?
Но ведь значения берутся разве не из таблицы? А поскольку такого значения там нет, то и с циклом все хорошо?
Realism_32 вне форума Ответить с цитированием
Старый 07.12.2013, 17:13   #29
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Покажите место в коде, где значения берутся из таблицы?
Вот и попробойте вызвать функцию со значением, которого нет в таблице...
waleri вне форума Ответить с цитированием
Старый 12.12.2013, 08:48   #30
nikmoon
Форумчанин
 
Регистрация: 13.11.2013
Сообщений: 149
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Покажите место в коде, где значения берутся из таблицы?
Вот и попробойте вызвать функцию со значением, которого нет в таблице...
Я прекрасно понимаю, с чем Вы несогласны. Можно доделать до универсальной версии.
Прога написана за полчаса на коленке, предполагая, что в исходном файле не будет символов, отсутствующих в кодировке koi8-r.
nikmoon вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Очень нужна помощь c матрицами, макросами в Excel. Заранее благодарен(поверьте, очень-очень нужна помощь) Farridjan Помощь студентам 1 03.07.2009 12:24
Очень нужна помощь с написанием программы... срочно(буду благодарен за помощь) 5Paladin5 Помощь студентам 3 02.07.2009 09:12
Очень нужна помощь! Нужно найти ошибку в очень простой программе. Lex55555777 Помощь студентам 3 07.12.2008 20:32