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

Статус
В этой теме нельзя размещать новые ответы.

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 Как бы решить проблему с буквой "ю"?
 
а ты конвертируй символы через самописные массивы
что-то типа
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 ($var, 0, 50);

			if (($temp_max = strrpos($var, '-')))  $var = substr ($var, 0, $temp_max);

	  }

  return $var;
}
только енто транслитерация
 
Я ж писал, что сначала пользовался и самопальной функцией. В обоих вариантах ботва с буквой "Ю". Даже 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);
}
 
попробуй вместо convert_cyr_string
заюзать iconv
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху