C# и кодировка символов

Adamastor

Client
Регистрация
15.05.2016
Сообщения
282
Благодарностей
14
Баллы
18
Здравствуйте уважаемое сообщество ZennoLab!

Подскажите пожалуйста как быть с кодировкой символов в C#?

У меня на данный момент две проблемы с кодировкой (насколько я понимаю) одну из которых я решил костылем, но вот выпрыгивает вторая и я понимаю что проблему надо попытаться решить в корне иначе я существенно загоню проект.

Итак проблема номер 1 и костыль для ее решения:

Суть в том что я паршу данные из одного из сайтов и сравниваю эти данные с данными из БД. Целью такого сравнения есть установление соответствия данных этого сайта с существующими в БД данными.

Функция посимвольного сравнения двух строк (привожу ниже код, не стоит углубляться пока, привожу его лишь для вашего удобства, может что-то потестировать надо будет если у вас появиться желание помочь разобраться) которая возвращает значение идентичности сравниваемых строк в процентах:

Код:
public static int StringCompare (string str1, string str2, int mode = 0) {
            if (str1 != null && str2 != null) {
                float compare_percent = 1.00F;
                float point = 0.0F;
                int lower_l, higher_l, index, prev = 0, koef = 1, vector = 1;
                string lower, higher;
              
                //const string symbols = "уеэоаяиюьы ";
              
                str1 = str1.ToLower();
                str2 = str2.ToLower();
              
                if (str1.Length > str2.Length) {
                    lower_l = str2.Length;
                    higher_l = str1.Length;
                    lower = str2;
                    higher = str1;
                } else {
                    lower_l = str1.Length;
                    higher_l = str2.Length;
                    lower = str1;
                    higher = str2;
                }
              
                //GV.proj.SendInfoToLog("Compare.  H = "+ higher_l + "; L = "+ lower_l+"; MODE = "+ mode.ToString());
              
                if ((mode == 2) && ((higher_l - lower_l) > 2)) return 0;
                if (lower_l != 0) {
                    point = (float) 1 / lower_l * 100;
                    for (int i = 0; i < lower_l; i++) {
                        index = higher.IndexOf(lower[i]);
                        if (index != -1) {
                            koef = 1;
                            //    Перевіряємо зміщення, якщо йде постійне зміщення - то букви не на своїх місцях
                            if (prev != index) {
                                if ((index - prev) < 0) vector = -1; else vector = 1;
                                koef += (index - prev) * vector;
                                prev = index;
                            }
                            /*if (mode == 2) {
                                if (higher.Substring(index, 1).IndexOfAny(symbols.ToCharArray()) != -1) koef += 1;
                            }*/
                            compare_percent += point / koef;
                            higher = higher.Remove(index, 1);
                        }
                        //project.SendInfoToLog("compare_percent = " + compare_percent.ToString() + "%");
                    }
                } else compare_percent = 0;
              
                //project.SendInfoToLog("lower_l - " + lower_l + " | lower - " + lower + " | higher_l - " + higher_l + " | higher - " + higher + " | point - " + point.ToString());
          
                return (int) compare_percent;
            } else return 0;
        }

Суть проблемы в том что задавая STR1 руками, а STR2 ногами (шутка) копируя например из текстового файла (с логами CodeCreator'а например) в котором кодировка Windows-1251 (ANSI в блокноте пишет), то ничего работать не будет. Функция сравнения строк вернет 0 даже если визуально строки идентичны.

Костыляка была придумана следующая (привожу код), суть ее в том что она посимвольно перебирает строку, каждый из символов путем switch-case заменяет на идентичный символ (но уже в нужной кодировке) и возвращает новую строку, перекодированную:

Код:
public static string RepareAll (string date) {
            string new_str = "";
            for (int i = 0; i < date.Length; i++) {
                switch (date[i])
                {
                    case '1':
                        new_str += "1";
                        break;
                    case '2':
                        new_str += "2";
                        break;
                    case '3':
                        new_str += "3";
                        break;
                    case '4':
                        new_str += "4";
                        break;
                    case '5':
                        new_str += "5";
                        break;
                    case '6':
                        new_str += "6";
                        break;
                    case '7':
                        new_str += "7";
                        break;
                    case '8':
                        new_str += "8";
                        break;
                    case '9':
                        new_str += "9";
                        break;
                    case '0':
                        new_str += "0";
                        break;
                    case 'й':
                        new_str += "й";
                        break;
                    case 'ц':
                        new_str += "ц";
                        break;
                    case 'у':
                        new_str += "у";
                        break;
                    case 'к':
                        new_str += "к";
                        break;
                    case 'е':
                        new_str += "е";
                        break;
                    case 'н':
                        new_str += "н";
                        break;
                    case 'г':
                        new_str += "г";
                        break;
                    case 'ш':
                        new_str += "ш";
                        break;
                    case 'щ':
                        new_str += "щ";
                        break;
                    case 'з':
                        new_str += "з";
                        break;
                    case 'х':
                        new_str += "х";
                        break;
                    case 'ё':
                        new_str += "ё";
                        break;
                    case 'ф':
                        new_str += "ф";
                        break;
                    case 'ы':
                        new_str += "ы";
                        break;
                    case 'в':
                        new_str += "в";
                        break;
                    case 'а':
                        new_str += "а";
                        break;
                    case 'п':
                        new_str += "п";
                        break;
                    case 'р':
                        new_str += "р";
                        break;
                    case 'о':
                        new_str += "о";
                        break;
                    case 'л':
                        new_str += "л";
                        break;
                    case 'д':
                        new_str += "д";
                        break;
                    case 'ж':
                        new_str += "ж";
                        break;
                    case 'э':
                        new_str += "э";
                        break;
                    case 'я':
                        new_str += "я";
                        break;
                    case 'ч':
                        new_str += "ч";
                        break;
                    case 'с':
                        new_str += "с";
                        break;
                    case 'м':
                        new_str += "м";
                        break;
                    case 'и':
                        new_str += "и";
                        break;
                    case 'т':
                        new_str += "т";
                        break;
                    case 'ь':
                        new_str += "ь";
                        break;
                    case 'б':
                        new_str += "б";
                        break;
                    case 'ю':
                        new_str += "ю";
                        break;
                    case '.':
                        new_str += ".";
                        break;
                    case 'Ё':
                        new_str += "Ё";
                        break;
                    case 'Й':
                        new_str += "Й";
                        break;
                    case 'Ц':
                        new_str += "Ц";
                        break;
                    case 'У':
                        new_str += "У";
                        break;
                    case 'К':
                        new_str += "К";
                        break;
                    case 'Е':
                        new_str += "Е";
                        break;
                    case 'Н':
                        new_str += "Н";
                        break;
                    case 'Г':
                        new_str += "Г";
                        break;
                    case 'Ш':
                        new_str += "Ш";
                        break;
                    case 'Щ':
                        new_str += "Щ";
                        break;
                    case 'З':
                        new_str += "З";
                        break;
                    case 'Х':
                        new_str += "Х";
                        break;
                    case 'Ъ':
                        new_str += "Ъ";
                        break;
                    case 'Ф':
                        new_str += "Ф";
                        break;
                    case 'Ы':
                        new_str += "Ы";
                        break;
                    case 'В':
                        new_str += "В";
                        break;
                    case 'А':
                        new_str += "А";
                        break;
                    case 'П':
                        new_str += "П";
                        break;
                    case 'Р':
                        new_str += "Р";
                        break;
                    case 'О':
                        new_str += "О";
                        break;
                    case 'Л':
                        new_str += "Л";
                        break;
                    case 'Д':
                        new_str += "Д";
                        break;
                    case 'Ж':
                        new_str += "Ж";
                        break;
                    case 'Э':
                        new_str += "Э";
                        break;
                    case 'Я':
                        new_str += "Я";
                        break;
                    case 'Ч':
                        new_str += "Ч";
                        break;
                    case 'С':
                        new_str += "С";
                        break;
                    case 'М':
                        new_str += "М";
                        break;
                    case 'И':
                        new_str += "И";
                        break;
                    case 'Т':
                        new_str += "Т";
                        break;
                    case 'Ь':
                        new_str += "Ь";
                        break;
                    case 'Б':
                        new_str += "Б";
                        break;
                    case 'Ю':
                        new_str += "Ю";
                        break;
                }
            }
          
            return new_str;
        }

После прогона STR2 через эту костыльную функцию функция сравнения строк начинает работать корректно.

Итак проблема номер 2 :

А проблема номер2 со странностью. И состоит она в том что часть (меньшая часть, примерно 20-30 записей из 4000-6000) не хочет добавляться в БД. Бред бредовый честно, вот я и решил что проблема опять в кодировке какой-то чтоли.

Я уже и написал (поскольку думал может MySQL тормозит/глючит) цикл состоящий из трех итераций в котором трижды пытаюсь добавить данные в БД, но они там так и не появляются. А вот когда я пытаюсь вручную внести эти же данные через вэб-интерфейс PHPMyAdmin - все добавляеться корректно!!! Аж нервы берут.

Вот функция по добавлению записей в БД:

Код:
public static string Add (string num, string ch, string cat_id) {
            string ch_id;
            ch_id = DB.Scalar("SELECT DISTINCT(`ID`) FROM `bk`.`ch` WHERE `name_"+ num +"`='"+ ch +"' AND `CAT_ID`=" + cat_id);
            for (int i = 0; i < 3; i++) {
                if (ch_id == "-") {
                    DB.NonQuery("INSERT INTO `bk`.`ch`(`name_"+ num +"`, `CAT_ID`) VALUES ('"+ ch +"', '"+ cat_id +"')");
                    ch_id = DB.Scalar("SELECT DISTINCT(`ID`) FROM `bk`.`ch` WHERE `name_"+ num +"`='"+ ch +"' AND `CAT_ID`=" + cat_id);
                } else break;
            }
          
            if (ch_id == "-") {
                GV.proj.SendInfoToLog("NUM - "+ num);
                GV.proj.SendInfoToLog("INSERT INTO `bk`.`ch`(`name_"+ num +"`, `CAT_ID`) VALUES ('"+ ch +"', '"+ cat_id +"')");
                GV.proj.SendInfoToLog("SELECT DISTINCT(`ID`) FROM `bk`.`ch` WHERE `name_"+ num +"`='"+ ch +"' AND `CAT_ID`=" + cat_id);
            }
          
            return ch_id;
        }

P.S. Пробовал гуглить и смотреть методы класса String в MSDN, не нашел ничего что мне нужно. Или его там нету или я что-то пропустил сквозь глаз.

ХЕЕЕЕЛП!!)))
 

kapelan28

Client
Регистрация
22.09.2015
Сообщения
469
Благодарностей
186
Баллы
43

Adamastor

Client
Регистрация
15.05.2016
Сообщения
282
Благодарностей
14
Баллы
18
а почему такая кодировка? как я понимаю, текст кириллический используется, для этого кодировка utf-8 нужно использовать.
Значит UTF-8 но непонятно какой.

Как проверить кодировку символов в C# не знаю(( Как ее определить и/или переформатировать строку в нужную кодировку также не знаю. В этом и состоит вопрос.

А факт в том что костыль помогает в первом случае. А во втором случае через костыль не пробовал - нету смысла в этом. Если во втором случае делать все через костыль, то из-за 20-ти записей из 4000-6000 придется их всех пропускать через костыль и нагружать программу( И таких проходов по 4000-6000 записей должно быть в разы больше, может быть 30-120 а то и больше, пока не определился (не дошел до этого этапа)
 

kapelan28

Client
Регистрация
22.09.2015
Сообщения
469
Благодарностей
186
Баллы
43
Как проверить кодировку символов в C# не знаю(( Как ее определить и/или переформатировать строку в нужную кодировку также не знаю. В этом и состоит вопрос.
Ставьте программу Notepad++ и будет счастье. Там и кодировку посмотреть можно и сменить кодировку легко.
Если файл содержит данные на кириллице, то кодировка должна быть - utf-8 без BOM (так и называется).
Приведите файлы к такой кодировке и попробуйте еще раз проделать те операции, которые выдавали ошибку.
 

Adamastor

Client
Регистрация
15.05.2016
Сообщения
282
Благодарностей
14
Баллы
18
Кхе кхе... Как обычно оказалось я дурак (во втором случае, в первом все действительно так).

У меня попросту поле в БД было на 50 символов, само собой если запись добавлялась на больше символов она обрезалась и уже не соответствовала оригиналу, от чего и все мои беды.

А в первом случае все действительно так по-дурацки.

Ставьте программу Notepad++ и будет счастье.
За совет спасибо огромное, действительно не догадался почему-то.
 
  • Спасибо
Реакции: kapelan28

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)