Что нового

[Данные, строки] Как "правильно" считать имена переменных и их значения из внешнего файла?

gora

Знающий
Сообщения
315
Репутация
19
Имеется внешний файл (умышленно не использую слово ini файл, хотя он и называется Settings.ini) следующего содержания:
Код:
;-------------- File of options -------------
Referal Link
; + Mode compression LZMA or LZMA2
modecomp=LZMA
; + Pattern of a name: filename_MC_DT_TM (filename - constant component)
pattern=MC,DT,TM
; + Name the sfx module
nameModule=7ZSD_LZMA.sfx
; Path to the folder of archiver 7-Zip
; + path7Zip=%ProgramFiles%\7-Zip\
path7Zip=%ProgramW6432%\7-Zip\
; + Percent use of RAM at compression. 1...100 (plus - Total RAM, minus - Free RAM)
useRAM=-90
; The command line for UPX
;cmdlinUPX=--best --all-methods
sizeForUPX=1000000
; Maximum icons size 32 - (32x32), 48 - (48x48)
maxicon=48
seticon=16,32,48,96
; + работает криво Number of extracted components 3...5
compnts=5
; + The maximum length of a file configuration in bytes
maxlen=12000
; A delay on moving of dialog boxes of SFX archive after their opening in milliseconds
; waitmov=80
; The timer on automatic closing of a message box about successful creation of SFX archive in seconds
timer=10
; + Endurance for imitation of unpacking archive in a dialog box "ExtractTitle" SFX archive in seconds
extractwait=300
; + Endurance for timer imitation in a dialog box "FinishMessage" SFX archive in seconds
finishwait=30
; + Delete of comments. Yes - 1, No - 0
delrem=1
; + Beep on start. Yes - 1, No - 0
beeper=0
; ========== Secret ===========
; dict=32
pass=gora
; +
criptArchive=0
; +
criptHdr=1
; Interface language. Russian - 1049, English - 1033
; lng=1031
; =============================
; Date of the first release of the program in format dd.MM.yyyy
fstbildat=17.12.2006
; Copyrights
-pv "1.16.0.%autobuild%"
-fv "1.16.0.%autobuild%"
-vs "ProductVersion=Version of a product 1.16.0"
-vs "FileVersion=Version of a file 1.16.0 build %autobuild%"
-vs "Comments=7z SXF archives"
-vs "CompanyName=Company"
-vs "FileDescription=7z SFX archive tool"
-vs "InternalName=Button for TC"
-vs "LegalCopyright=©"
-vs "LegalTrademarks=Still is not present"
-vs "OriginalFilename=Button.exe"
-vs "PrivateBuild=%date%"
-vs "ProductName=#1.16.0"
-vs "SpecialBuild=Only for users TC ;)"

Для считывания имен переменных и их значений из этого файла использую следующий код:
Код:
Dim $fcprt, $errN, $copir
;	переменные из ini файла, если закомментированы
Dim $modecomp='LZMA', $pattern='MC,DT,TM', $nameModule='7ZSD_LZMA.sfx', $path7Zip='%ProgramW6432%\7-Zip\', $useRAM='100', $compnts=4, $maxlen=12000, $extractwait=300, $finishwait=30, $delrem=1, $beeper=1, $criptArchive=0, $criptHdr=1

;	чтение Settings.ini 
$file = FileOpen("Settings.ini", 0)
If $file = -1 Then
    MsgBox(0,"", 'Файл "Settings.ini" отсутствует!!!')
	Exit
EndIf
While 1
	$line = FileReadLine($file)
	If @error = -1 Then ExitLoop
	If StringLeft($line, 1) <> ";" Then
		If $errN = 0 Then
			$errN = 1
			If $line <> "Referal Link" Then $fcprt = 1
		Else
			If StringLeft($line, 1) = "-" Then
				$copir &= " " & $line
			Else
				$array = StringSplit($line, "=")
				Assign($array[1], $array[2], 2)
			EndIf
		EndIf
	EndIf
Wend
FileClose($file)

If Not IsDeclared ("seticon") Then
    MsgBox(0,"", "Переменная seticon не определена в ini файле")
Else
    MsgBox(0,"", "Переменная seticon = " & Eval("seticon"))
EndIf


Этот код работает, но мне уже не раз здесь говорили, что он "неправильный".
Obfuscator при запуске ругается на строку Assign($array[1], $array[2], 2)

Подскажите, а как же "правильно" считывать и имена переменных, и их значения из внешнего файла?

Спасибо.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
gora

Для начала в свой ini в первую строку добавь [set] и проверяй мой пример с ним.

Код:
$Ini=@ScriptDir&'\Settings.ini'
$aIni=IniReadSection($Ini, 'set')

; смотрим какой красивый массив
#include <Array.au3>
_ArrayDisplay($aIni, 'Array')

; создаём переменные
For $i = 1 to $aIni[0][0]
	Assign($aIni[$i][0], $aIni[$i][1])
Next


; читаем переменные
$text=''
For $i = 1 to $aIni[0][0]
	$text&=Eval($aIni[$i][0])&@CRLF
Next
MsgBox(0, 'Вот оно', $text)


Обычно я этот метод использую для русификации, но ещё интересное применение вижу - быстрый поиск соответствия. Не нужно искать имя перебирая двумерный массив, достаточно прочитать переменную с этим именем.
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
AZJIO [?]
И вообще то при таком небольшом массиве не обязательно применять Assign. Массив уже содержит необходимое, просто сделай функцию поиска _ArraySearch, находишь индекс, читаешь значение.
Я не понял как это, можно пример?
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
gora
Я не понял как это, можно пример?
спрашивается для чего я функции даю? Чтоб самому же и делать?

Код:
#include <Array.au3>
$aIni=IniReadSection($@ScriptDir&'\Settings.ini', 'set')
MsgBox(0, 'Вот оно', $aIni[_ArraySearch($aIni, '-vs "FileVersion')][1])
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
AZJIO [?]
Чтоб самому же и делать?
Ну потерпите немного, я ж только учусь.

Если я Вас правильно понял, то вместо переменной $path7Zip в скрипте, я должен везде буду использовать выражение:
Код:
$aIni[_ArraySearch($aIni, 'path7Zip')][1]

1 Это конечно усложнит скрипт, т.к., переменная используется около 20 раз.
2 Остался вопрос, как быть с предустановленным значением этой переменной? У меня она определена во второй строке скрипта, а тут получается, что и переменной $path7Zip у меня в скрипте больше не будет??
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
gora
почему бы не использовать IniRead?

Код:
$path7Zip=IniRead($Ini, 'set', 'path7Zip', '%ProgramW6432%\7-Zip\')
 
Верх