Что нового

[Ошибки] Проблемы с перекодировкой в простом парсере

akoulev

Новичок
Сообщения
166
Репутация
2
Есть (всё ещё) заготовка парсера, которая открывает текстовый файл, построчно считывает из него строки, отображает эти строки -по очереди- на экране и записывает их (строки) в новый файл.
Вчера парсер научился отображать эти строки правильно (т.е., конвертировать из исходной 886 кодовой страницы в 1251-ю — с помощью функции _WinAPI_OemToChar).
Беда пришла, откуда не ждали: при записи новополученных строк в 1251-й кодировке в файл, — строки сохраняются, но уже в совершенно нечитаемом виде (русские слова -при просмотре файла- отображаются в перекодировке). Почему оно не может нормально записать то, что само же и сгенерировало (и сгенерировало правильно!) — неясно; как победить — неясно тем более. :stars:

Код:
#include <FileConstants.au3>
#include <MsgBoxConstants.au3>
#include <WinAPIFiles.au3>
#include <Array.au3>
#include <File.au3>

Global $Gde_hran_istok = "C:\tmp\"
Global $istok = "net_user.txt"
Global $stok = "net_user_output.txt"
Global $CountLines = 0; сколько строк? Default = 0
Local $sFilePath = $Gde_hran_istok&$istok
Local $sFilePathOut = $Gde_hran_istok&$stok
Global $hFileOpen = FileOpen($sFilePath, $FO_READ )
Global $Shtirlits = 0

If_are_FILES()

SkokaStrok(); скока строк, файл ИСТОК?

Local $i=1
While 1
	  Global $sFileRead = FileReadLine ($hFileOpen, $i)

$sFileRead = _WinAPI_OemToChar($sFileRead); http://autoit-script.ru/index.php?topic=21594.0#msg126928

		 Local $Tri_levih = StringTrimRight ($sFileRead,StringLen ($sFileRead)-3)
		; MsgBox (0,"***",$Tri_levih ,2)

				 If $Tri_levih = "---" Then
					$Shtirlits =1
				 Else
					; них
				 EndIf

										  MsgBox (0,"XXX","Строка № " & $i & ", её значение: " & $sFileRead ,1.1)
										  If  $Shtirlits =1 Then
											Writttte()
										  Else
										  EndIf


	  $i=$i+1
	  If $i=$CountLines+1 Then ExitLoop
      WEnd
   FileClose($hFileOpen)
   FileClose($hFileOpenOUT)
Exit



; Далее идут функции



Func If_are_FILES(); есть ли файлы ИСТОК и СТОК?
	  If $hFileOpen = -1 Then
        MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading the ISTOK-file.")
        Return False
    EndIf

; Open the file for read/write access.
   Global $hFileOpenOut = FileOpen($sFilePathOut, $FO_READ + $FO_APPEND)
   ;Local $hFileOpen    = FileOpen($sFilePath,    $FO_READ + $FO_OVERWRITE)
    If $hFileOpenOut = -1 Then
        MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading/writing the OUT-file.")
        Return False
    EndIf
EndFunc



Func SkokaStrok(); скока строк, файл ИСТОК? — _FileCountLines


	$CountLines = _FileCountLines($sFilePath)
   If @error Then
	   MsgBox(0, 'Ошибка', 'Не найден файл')
   Else
	   MsgBox(64, "Результат", "В файле net_user.txt всего " & $CountLines & " строк.", 2)
	EndIf
EndFunc



Func Writttte()
   ;$hFileOpen = FileOpen($sFilePathOut, $FO_READ + $FO_OVERWRITE)
  FileWrite($hFileOpenOUT, $sFileRead & @CRLF)
;[optional] Mode to open the file in.
;Can be a combination of the following:
;    $FO_READ (0) = Read mode (default)
;    $FO_APPEND (1) = Write mode (append to end of file)
;    $FO_OVERWRITE (2) = Write mode (erase previous contents)
;    $FO_CREATEPATH (8) = Create directory structure if it doesn't exist (See Remarks).
;    $FO_BINARY (16) = Force binary mode (See Remarks).
;    $FO_UNICODE or $FO_UTF16_LE (32) = Use Unicode UTF16 Little Endian reading and writing mode.
;    $FO_UTF16_BE (64) = Use Unicode UTF16 Big Endian reading and writing mode.
;    $FO_UTF8 (128) = Use Unicode UTF8 (with BOM) reading and writing mode.
;    $FO_UTF8_NOBOM (256) = Use Unicode UTF8 (without BOM) reading and writing mode.
;    $FO_ANSI (512) = Use ANSI reading and writing mode.
;    $FO_UTF16_LE_NOBOM (1024) = Use Unicode UTF16 Little Endian (without BOM) reading and writing mode.
;    $FO_UTF16_BE_NOBOM (2048) = Use Unicode UTF16 Big Endian (without BOM) reading and writing mode.
;    $FO_FULLFILE_DETECT (16384) = When opening for reading and no BOM is present, use the entire file to determine if it is UTF8 or UTF16. If this is not used then only the initial part of the file (up to 64KB) is checked for performance reasons.
;The folder path must already exist (except using $FO_CREATEPATH mode - See Remarks).
;
;Constants are defined in FileConstants.au3.

EndFunc


На входе (файл net_user.txt в директории C:\tmp\):
Код:
Учетные записи пользователей для \\Один_комп

-------------------------------------------------------------------------------
ASPNET                   HelpAssistant            SUPPORT_388945a0
Администратор            Гость
Команда выполнена успешно.
D:\Documents and Settings\Один_user


На вЫходе — файл net_user_output.txt:
Код:
-------------------------------------------------------------------------------
ASPNET                   HelpAssistant            SUPPORT_388945a0
Администратор            Гость
Команда выполнена успешно.
D:\Documents and Settings\РћРґРёРЅ_user


Ай нид хелп, плиз! (с) Некто Данила Багров.
 

Вложения

joiner

Модератор
Локальный модератор
Сообщения
3 200
Репутация
540
Re: [Ошибки] [Ошибки] Парсер СНОВА не умеет "в перекодировку"

все работает
дескриптор файла нужно закрывать, это так, к слову
AutoIT 3.3.12.0
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Re: [Ошибки] Парсер СНОВА не умеет "в перекодировку"

akoulev сказал(а):
Предупреждение За нарушение общих правил (пункт В.8):
Так как эта конференция называется "Русское сообщество AutoIt", язык общения на ней - Русский. Названия фирм или программных продуктов, аббревиатуры и т.д. должны быть написаны так, как они пишутся в оригинале, например не следует писать УСБ вместо USB. На форуме крайне не рекомендуется намеренно искажать русский язык и использовать "сетевой жаргон" на подобии "Аффтар выпей йадау!".


С уважением, ваш Модератор.
 
Автор
A

akoulev

Новичок
Сообщения
166
Репутация
2
Re: [Ошибки] Парсер СНОВА не умеет "в перекодировку"

joiner сказал(а):
все работает
дескриптор файла нужно закрывать, это так, к слову
AutoIT 3.3.12.0
Дескрипторы проставил; спасибо. Но "больному это не помогло": в файле вывода по-прежнему нечитаемые символы вместо русских букв. У меня стоИт AutoIt Version: 3.3.14.2 — полагаете, стОит откатиться на 12 версию? Или лучше подняться до нынешней 15-й?

2_Yashied : Извините, и я всё поправил. Не знал, что нельзя даже поздороваться английской фразой. Если вдруг что-то упустил, то неспециально.

По сути вопроса: да, ПОЧТИ всё работает. Far manager кодировку UTF-8 желал отобразить или как 866 страницу, или как 1251-ю. Но, если я просто нажимаю Enter на выходном файле — он открывается в блокноте и нормально отображается. Поставил себе (чего и всем желаю) Notepad++ (январский, этого года, ver.6.8.9, https://notepad-plus-plus.org/news/notepad-6.8.9-released.html) — он всегда сообщает (внизу, справа), в какой же кодировке файл.
Однако, проблема-то осталась (хотя и несколько потеряла остроту): хотя я и вижу текст, но исходник — в 866 странице, а полученный файл — в UTF-8. Как бы всё-таки получить свежезаписанный файл во всё той же 866 кодировке? Ну, раз уж мы с неё начали, — неплохо бы в ней и оставаться.
 

joiner

Модератор
Локальный модератор
Сообщения
3 200
Репутация
540
Re: [Ошибки] Парсер СНОВА не умеет "в перекодировку"

функция
Код:
FileOpen

имеет режимы открытия файла (к слову о кодировках)
как исходного, так и того, который записывается. если тебе нужно просто скопировать файл в другое место с другим именем, то нужно читать его в бинарном режиме и записывать так же. тогда все будет ок
 
Автор
A

akoulev

Новичок
Сообщения
166
Репутация
2
Re: [Ошибки] Парсер СНОВА не умеет "в перекодировку"

joiner сказал(а):
...режимы открытия файла (к слову о кодировках)
как исходного, так и того, который записывается.
Спасибо ещё раз; буду "переваривать".

joiner сказал(а):
если тебе нужно просто скопировать файл в другое место с другим именем, то нужно читать его в бинарном режиме и записывать так же. тогда все будет ок
Ну, разумеется, нет. Там много всяко-забавного будет, в этом парсере; вот добью проблему с перекодировками — и начну реализовывать "планов громадьё". Ещё раз спасибо. :laugh:
 

InnI

AutoIT Гуру
Сообщения
4 371
Репутация
1 178
Re: [Ошибки] Парсер СНОВА не умеет "в перекодировку"

akoulev
раз уж мы с неё начали, — неплохо бы в ней и оставаться
Зачем? Конвертнули, распарсили... и опять конвертить?! :stars:
Код:
#include <WinAPIMisc.au3>

$str = "сохраняем ANSI-строку в кодировке 866"

; вариант 1
$f = FileOpen("test1.txt", 2 + 1024)
$dos = _WinAPI_CharToOem($str)
FileWrite($f, $dos)
FileClose($f)

; вариант 2
$f = FileOpen("test2.txt", 2 + 512)
$aRet = DllCall('user32.dll', 'bool', 'CharToOemA', 'str', $str, 'str', '')
$dos = $aRet[2]
FileWrite($f, $dos)
FileClose($f)
Лучше сразу парсер под 866 написать...
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
Re: [Ошибки] Парсер СНОВА не умеет "в перекодировку"

Предупреждение За нарушение правил форума (пункт Б.5):
Имя темы должно нести смысловую нагрузку (отражать суть вопроса/проблемы)
Правильно сформулированное название темы привлекает больше внимания, и шансы получить конкретный ответ увеличиваются.


Данные правила могут пополняться локальными правилами раздела.
Как правильно называть темы

"[Ошибки] Парсер СНОВА не умеет "в перекодировку"" - это неприемлемое название темы, переименуйте тему иначе она будет закрыта, а вам возможно будет выдан бан на несколько дней.

С уважением, ваш Глобальный модератор.
 
Автор
A

akoulev

Новичок
Сообщения
166
Репутация
2
Тему переименовал.
 
Верх