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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.12.2013, 19:02   #11
Realism_32
Пользователь
 
Регистрация: 01.12.2013
Сообщений: 17
По умолчанию

Кстати, ведь из utf-8 в ср1251 можно перейти побитовым сдвигом влево?
Или я что-то не так понял.
Realism_32 вне форума Ответить с цитированием
Старый 02.12.2013, 19:53   #12
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Цитата:
Сообщение от Realism_32 Посмотреть сообщение
Благодарю, сижу осмысляю как работает )
1. определяемся с именами входного-исходного файла и настраиваемся под переданные параметры обработки.
2. сторонней функцией перегоняем в массив utf16 (каковой соответствует Unicode-таблице). (здесь необходима обработка ее ошибок)
3. конструируем хэшмапу, а то иначе придется тупо в цикле первбирать все допустимые для Koi-8 символы Юникода, что в ~150 раз дольше поиска по хэшу.
4. резервируем память в результирующей строке. (не проверял, а сбрасывается ли аллокированная память после добавления очередного символа?)
5. ищем по хешу Кои-соответствия и добавляемся в результат. (Случай ненахождения обрабатывается весьма коряво.)
6. пишем результат

Цитата:
Сообщение от Realism_32 Посмотреть сообщение
Кстати, ведь из utf-8 в ср1251 можно перейти побитовым сдвигом влево?
Или я что-то не так понял.
М-м-м... не уверен Побитовые сдвиги равнозначны умножению/делению на степень двойки, а не прибавлению/отнятию константного числа.

В ср1251 все расположено примерно по алфавиту, так что можно было бы обойтись и прибавлением константы, если обрабатывать отдельно: 1. конверт строчных 2. конверт заглавных 3. конверт ё маленькой 4. конверт Ё большой 5. конверт латиницы со знаками препинания из первой половины ср1251таблицы... да учитывать, что utf8 разный по длине и допускает использование нескольких кодов для одного символа.

Кароч, мутно. Проще сделать полное посимвольное соответствие в хеше, так получим понятность и выиграем в скорости)

Последний раз редактировалось Smogg; 02.12.2013 в 20:06.
Smogg вне форума Ответить с цитированием
Старый 02.12.2013, 21:07   #13
Realism_32
Пользователь
 
Регистрация: 01.12.2013
Сообщений: 17
По умолчанию

Вот, спасибо за подробный разбор по пунктам. очень кстати )


Код ведь заработает на Си? Линукс.
Просто, только-только начал изучение этого языка и врятли понимаю как код из С++ сделать удобоваримым для компилятора gcc Си.
допустим cout и cin ясно на что заменяются...
Realism_32 вне форума Ответить с цитированием
Старый 02.12.2013, 21:42   #14
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Цитата:
Сообщение от Realism_32 Посмотреть сообщение
Вот, спасибо за подробный разбор по пунктам. очень кстати )
Мне тоже тяжело читать код без пояснений.

Цитата:
Код ведь заработает на Си? Линукс.
Просто, только-только начал изучение этого языка и врятли понимаю как код из С++ сделать удобоваримым для компилятора gcc Си.
допустим cout и cin ясно на что заменяются...
На Си - нет.
Тока зачем Вам этот хардкор? Я не верю, что есть системы, где не можно быть С++.
Smogg вне форума Ответить с цитированием
Старый 02.12.2013, 21:49   #15
Realism_32
Пользователь
 
Регистрация: 01.12.2013
Сообщений: 17
По умолчанию

Я с большим удовольствием избежал бы этого хардкора... Дело в том что это одна из моих лабораторных. Сделал все остальные и уже давно сдал, а с этим чудом вожусь еженощно уже третью неделю. Поскольку изучаем только Си, да еще и в Линуксе... соответственно работы тоже принимают в Си.
Realism_32 вне форума Ответить с цитированием
Старый 02.12.2013, 22:09   #16
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

А-аа... Тогда вам нужно делать собственную реализацию конверта Utf8 в Utf16.
И лишь после того, как что-то начнет получатся, можно посмотреть, как же люди решили ту же задачу. Собственно, в этом и весь смысл.

Как я понял, значимые биты в Utf8 в идут в том же порядке, как и в Utf16? Да?

То есть, нужно определить, что является служебной информацией, выбросить ее, а потом сдвинуть остаток в один ushort.
Smogg вне форума Ответить с цитированием
Старый 02.12.2013, 22:17   #17
Realism_32
Пользователь
 
Регистрация: 01.12.2013
Сообщений: 17
По умолчанию

Цитата:
Сообщение от Smogg Посмотреть сообщение
А-аа... Тогда вам нужно делать собственную реализацию конверта Utf8 в Utf16.
И лишь после того, как что-то начнет получатся, можно посмотреть, как же люди решили ту же задачу. Собственно, в этом и весь смысл.

Как я понял, значимые биты в Utf8 в идут в том же порядке, как и в Utf16? Да?

То есть, нужно определить, что является служебной информацией, выбросить ее, а потом сдвинуть остаток в один ushort.

да, получается что так. Поэтому у меня и возникла мысль про сдвиг.
После реализации в Utf16 задумал перевести все там же в ср1251, так как из нее я имею представление как перекодировать в koi8
Realism_32 вне форума Ответить с цитированием
Старый 03.12.2013, 08:49   #18
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Будет гораздо проще переводить из utf16 прямо в koi.
waleri вне форума Ответить с цитированием
Старый 03.12.2013, 09:12   #19
nikmoon
Форумчанин
 
Регистрация: 13.11.2013
Сообщений: 149
По умолчанию

Будет работать только для 1-о и 2-х байтовых символов UTF-8
Код:
#include <iostream>
#include <cstring>
using namespace std;

// вторая часть таблицы кодировки для перевода из 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()
{
	// значения для проверки, UTF-8, 2 кириллических символа 'К'
	unsigned short arr[] = { 0x9AD0, 0x9AD0, 0x0000 };

	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';	// устанавливаем признак конца строки
	cout << strKOI8R << endl;
	return 0;
}
nikmoon вне форума Ответить с цитированием
Старый 04.12.2013, 18:30   #20
Realism_32
Пользователь
 
Регистрация: 01.12.2013
Сообщений: 17
По умолчанию

nikmoon, спасибо большое! Данный код прекрасно работает на Си, после некоторых изменений. Постараюсь приспособить его под файловый ввод-вывод и выложу.
Realism_32 вне форума Ответить с цитированием
Ответ


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



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