Windows XP, DOS и консольные приложения

Тема в разделе "PHP", создана пользователем sartiii, 27 ноя 2008.

Статус темы:
Закрыта.
Модераторы: latteo
  1. sartiii

    sartiii Постоялец

    Регистр.:
    17 сен 2008
    Сообщения:
    105
    Симпатии:
    17
    Всем известно, что Windows XP (мой SP1) имеет одну хорошую особенность - по умолчанию работает в консоли с досовской кодировкой (866). У меня есть консольное приложение, написанное под Windows и работает с кодировкой CP-1251. Оно получает на вход некие данные, как латиницей так и кириллицей.
    Делаю вызов так:
    echo мой конь очень слаб | exe.exe
    И получаю в ответ руны. Ибо прога возвращает результат в кодировке CP-1251, а консоль работает в режиме 866.

    Хорошо, делаю chcp 1251 и консоль начинает работать в режиме кодировки CP-1251.
    Но при вводе русских букв получается что-то типа: ьющ ъюэ№ юўхэ№ ёырс. Ну да хрен с ним.
    echo ьющ ъюэ№ юўхэ№ ёырс | exe.exe выводит результат такими же каракулями, но верно обработанный той прогой.

    Далее поменял в свойствах командной строки шрифт с точечного на Lucida Console. Каракули заменились на кириллические символы. Всё шикарно!

    Но дело в другом, обработать нужно мильён записей. Поэтому был написан PHP скрипт, который циклом делает exec('echo $data[$i] | exe.exe)', $p);. Соотвественно выводится чушь. Предварительно кодирую строку (CP-1251) в DOS -> WIN (так посоветовал Штирлиц) с помощью самопальной функции и всё работает шикарно. Но есть один косяк, при таком (двойном) кодировании вместо буквы "ю" получается буква "о".

    Хорошо, стал конвертировать встроенной функцией. convert_cyr_string($text, 'd', 'w') тоже работает, но опять вместо "ю" выводится " ".

    А теперь вопросы:
    #1 Что за фигня?
    #2 Так у всех или мой Windows подвёл меня?
    #3 Как бы решить проблему с буквой "ю"?
     
  2. Mongolor

    Mongolor

    Регистр.:
    5 дек 2007
    Сообщения:
    157
    Симпатии:
    29
    а ты конвертируй символы через самописные массивы
    что-то типа
    PHP:
    function totranslit($var)
    {
            
    $NpjLettersFrom "абвгдезиклмнопрстуфцыі";
            
    $NpjLettersTo   "abvgdeziklmnoprstufcyi";
            
    $NpjBiLetters = array( 
          
    "й" => "jj""ё" => "jo""ж" => "zh""х" => "kh""ч" => "ch"
          
    "ш" => "sh""щ" => "shh""э" => "je""ю" => "ju""я" => "ja",
          
    "ъ" => """ь" => """ї" => "yi""є" => "ye",
                                  );

            
    $NpjCaps  "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЪЫЭЮЯЇЄІ";
            
    $NpjSmall "абвгдеёжзийклмнопрстуфхцчшщьъыэюяїєі";

          
    $var str_replace(".php"""$var);
          
    $var trim(strip_tags($var));
          
    $var preg_replace"/\s+/ms""-"$var );
          
    $var strtr$var$NpjCaps$NpjSmall );
          
    $var strtr$var$NpjLettersFrom$NpjLettersTo );
          
    $var strtr$var$NpjBiLetters );

          
    $var preg_replace("/[^a-z0-9\_\-.]+/mi"""$var);
          
    $var=preg_replace('#[\-]+#i''-'$var);
          
    $var strtolower $var );

          if (
    strlen($var) > 50) {

            
    $var substr ($var050);

                if ((
    $temp_max strrpos($var'-')))  $var substr ($var0$temp_max);

          }

      return 
    $var;
    }
    только енто транслитерация
     
  3. sartiii

    sartiii Постоялец

    Регистр.:
    17 сен 2008
    Сообщения:
    105
    Симпатии:
    17
    Я ж писал, что сначала пользовался и самопальной функцией. В обоих вариантах ботва с буквой "Ю". Даже shtirlitzIV тот же косяк делает =(

    PHP:
    // ПРЕОБРАЗОВАНИЕ DOS TO WIN
    function dtw($text){
        
    $cout '';
        for(
    $i=0;$i<strlen($text);$i++) {
            
    $ord=ord($text[$i]);
            if(
    $ord>=128&&$ord<=175$cout.=chr($ord+64);
            elseif(
    $ord>=224&&$ord<=239$cout.=chr($ord+16);
            elseif(
    $ord==240$cout.=chr(168);
            elseif(
    $ord==241$cout.=chr(184);
            elseif(
    $ord==252$cout.=chr(185);
            elseif(
    $ord==45$cout.=chr(151);    //150
            
    elseif($ord==34$cout.=chr(147);    //147,148,171,187
            
    elseif($ord==196$cout.=chr(151);
            elseif(
    $ord==242$cout.=chr(170);
            elseif(
    $ord==243$cout.=chr(186);
            elseif(
    $ord==244$cout.=chr(175);
            elseif(
    $ord==245$cout.=chr(191);
            elseif(
    $ord==246$cout.=chr(161);
            elseif(
    $ord==247$cout.=chr(162);
            elseif(
    $ord==248$cout.=chr(176);
            elseif(
    $ord==249$cout.=chr(149);
            elseif(
    $ord==250$cout.=chr(183);
            elseif(
    $ord==253$cout.=chr(164);
    //        elseif($ord==254) $cout.=chr(154);
            
    elseif($ord==255$cout.=chr(160);
    //        elseif($ord>=128&&$ord<=190) $i=$i; //нет представления данному символу
            
    else $cout.=chr($ord);
        }
        return(
    $cout);
    }
     
  4. Mongolor

    Mongolor

    Регистр.:
    5 дек 2007
    Сообщения:
    157
    Симпатии:
    29
    попробуй вместо convert_cyr_string
    заюзать iconv
     
Статус темы:
Закрыта.