Транслит во все поля

 


Три занимался одной задачей. Накопилось у меня около 400 картинок с ресурса Historicana, названных неправильно. Каждая картинка - это описание исторического момента. Короче, решил добавить к .jpg комментарии и переименовать файло. Подумалось, что удобнее взять транслит. И понеслись злоключения.

Начнем с того, что готовая либа JPEG сделана через жопу. Например, с трудом скомпилированный wrjpgcom.c выплевывает в консоль данные, и получается не картинка, а мусор. Пострадал немного, плюнул и сел за код. По идее проще всего искать маркеры картинки, пропускать комментарий или, если он не найден, то вписывать до $FFDA. Наверняка криворукие кодеры обработают неверно. Наплевать, некоторые программы справляются корректно.

Написал код(prb.pb) и из 200 картинок получилось меньше. стал искать, в чем причина, нашел в отладочном логе. Причина в некорректном имени файла, некоторые буквы ё и й отображаются как unicode. Справился с 16ю неверными именами, осталось переводить имя в транслит.

Эта задача совпала с  проектом, над которым я занимался. Только вышла unicode-версия, которая мне и помогла. Беру старые программы, добавляю текст и вместо имени в unicode вижу "???".

"Филипп, ты влип". Дописал код, который было лень доделывать, переименовал все файлы. Количество совпало, это радует. Осталось 300 картинок, к которым добавлены текстовые файлы, не знаю, что делать.

Короче, вернулся к транслиту и решил написать две функции на TinyC. Писал код с соплями и матом - я Си не знаю и кое-что не понимаю. Сделал улучшенный код транслита, но вынести код в функцию не удалось. И да и выполнение обратной функции детранслитерации превратилось бы в очередной кошмар разработки. Переписал заново и дополнил код. Теперь у меня есть готовая библиотека. Папка tcc - пример, tcc_lib - либа, перекомпилированная на lcc-win32.

Почему я взялся за этот геморрой? Вот пример, найденный в интернетах:

#include <stdio.h>

#include <conio.h>

#include "string.h"


void Transliterate(char* str, char* newStr)

{

        for (; *str != 0; str++)

        {

                switch (str[0])

                {

                case 'а': strcat(&newStr[0], "a"); break;

                case 'б': strcat(&newStr[0], "b"); break;

                case 'в': strcat(&newStr[0], "v"); break;

                case 'г': strcat(&newStr[0], "g"); break;

                case 'д': strcat(&newStr[0], "d"); break;

                case 'е': strcat(&newStr[0], "e"); break;

                case 'ё': strcat(&newStr[0], "ye"); break;

                case 'ж': strcat(&newStr[0], "zh"); break;

                case 'з': strcat(&newStr[0], "z"); break;

                case 'и': strcat(&newStr[0], "i"); break;

                case 'й': strcat(&newStr[0], "y"); break;

                case 'к': strcat(&newStr[0], "k"); break;

                case 'л': strcat(&newStr[0], "l"); break;

                case 'м': strcat(&newStr[0], "m"); break;

                case 'н': strcat(&newStr[0], "n"); break;

                case 'о': strcat(&newStr[0], "o"); break;

                case 'п': strcat(&newStr[0], "p"); break;

                case 'р': strcat(&newStr[0], "r"); break;

                case 'с': strcat(&newStr[0], "s"); break;

                case 'т': strcat(&newStr[0], "t"); break;

                case 'у': strcat(&newStr[0], "u"); break;

                case 'ф': strcat(&newStr[0], "f"); break;

                case 'х': strcat(&newStr[0], "kh"); break;

                case 'ц': strcat(&newStr[0], "tc"); break;

                case 'ч': strcat(&newStr[0], "ch"); break;

                case 'ш': strcat(&newStr[0], "sh"); break;

                case 'щ': strcat(&newStr[0], "shch"); break;

                case 'ъ': strcat(&newStr[0], "''"); break;

                case 'ы': strcat(&newStr[0], "y"); break;

                case 'ь': strcat(&newStr[0], "''"); break;

                case 'э': strcat(&newStr[0], "e"); break;

                case 'ю': strcat(&newStr[0], "iu"); break;

                case 'я': strcat(&newStr[0], "ia"); break;

                case 'А': strcat(&newStr[0], "A"); break;

                case 'Б': strcat(&newStr[0], "B"); break;

                case 'В': strcat(&newStr[0], "V"); break;

                case 'Г': strcat(&newStr[0], "G"); break;

                case 'Д': strcat(&newStr[0], "D"); break;

                case 'Е': strcat(&newStr[0], "E"); break;

                case 'Ё': strcat(&newStr[0], "Ye"); break;

                case 'Ж': strcat(&newStr[0], "ZH"); break;

                case 'З': strcat(&newStr[0], "Z"); break;

                case 'И': strcat(&newStr[0], "I"); break;

                case 'Й': strcat(&newStr[0], "Y"); break;

                case 'К': strcat(&newStr[0], "K"); break;

                case 'Л': strcat(&newStr[0], "L"); break;

                case 'М': strcat(&newStr[0], "M"); break;

                case 'Н': strcat(&newStr[0], "N"); break;

                case 'О': strcat(&newStr[0], "O"); break;

                case 'П': strcat(&newStr[0], "P"); break;

                case 'Р': strcat(&newStr[0], "R"); break;

                case 'С': strcat(&newStr[0], "S"); break;

                case 'Т': strcat(&newStr[0], "T"); break;

                case 'У': strcat(&newStr[0], "U"); break;

                case 'Ф': strcat(&newStr[0], "F"); break;

                case 'Х': strcat(&newStr[0], "Kh"); break;

                case 'Ц': strcat(&newStr[0], "TC"); break;

                case 'Ч': strcat(&newStr[0], "Ch"); break;

                case 'Ш': strcat(&newStr[0], "Sh"); break;

                case 'Щ': strcat(&newStr[0], "ShCh"); break;

                case 'Ъ': strcat(&newStr[0], "''"); break;

                case 'Ы': strcat(&newStr[0], "Y"); break;

                case 'Ь': strcat(&newStr[0], "''"); break;

                case 'Э': strcat(&newStr[0], "E"); break;

                case 'Ю': strcat(&newStr[0], "IU"); break;

                case 'Я': strcat(&newStr[0], "IA"); break;

                default: { char Temp[2] = { str[0], 0} ; strcat(&newStr[0], &Temp[0]); }

                }

        }

}


int main()

{

        char* x = "Привет мир!";

        char y[100] = {0};

        Transliterate(x, &y[0]);

        printf("%s\n", y);

return 0;

}


Вышло 4.5 Кб, моя программа 3.5Кб.

Теперь о программе, над которой я работал.


В нее включена кодировка по ГОСТу, над другими я не работал. Надеюсь, что сделано верно, хотя над алгоритмом надо еще поработать.

Архив всех переделок.

Комментарии