Что нового

Не добавлять в массив пустые (не сществующие) строки (из несуществующей переменной)

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
Добрый день. Получаю кучу всяких смарт данных винчестера и слаживаю их в массив. Зарезервированных значений много. Но не все используются различными производителями, поэтому массив каждый раз разный по размеру, и ложить пустую строку (пустое значение переменной) в массив не хочется. Делаю так:
Код:
#include <Constants.au3>
#include <Array.au3>

Const $wbemFlagReturnImmediately = 0x10
Const $wbemFlagForwardOnly = 0x20
Global  $Smart[0][8]
Global $sTemp, $sTemp231, $sTemp1

$objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\WMI")
$colItems = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_ATAPISmartData", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    $iCnt = 1
       For $Item In $colItems
                $strReserved = $Item.Reserved
                $strVendorSpecific = $Item.VendorSpecific
        $iCnt +=1
 Next
   For $i = 2 to UBound($strVendorSpecific) - 1 Step 12
    If $strVendorSpecific[$i] == 0 then ContinueLoop
   If $strVendorSpecific[$i] = 1 Then $sPark = $strVendorSpecific[$i] &'|'& $strVendorSpecific[$i + 1] &'|'& $strVendorSpecific[$i + 2] &'|'& $strVendorSpecific[$i + 3] &'|'& $strVendorSpecific[$i + 4] &'|'& $strVendorSpecific[$i + 5] &'|'& $strVendorSpecific[$i + 6]
   If $strVendorSpecific[$i] = 2 Then $sP = $strVendorSpecific[$i] &'|'& $strVendorSpecific[$i + 1] &'|'& $strVendorSpecific[$i + 2] &'|'& $strVendorSpecific[$i + 3] &'|'& $strVendorSpecific[$i + 4] &'|'& $strVendorSpecific[$i + 5] &'|'& $strVendorSpecific[$i + 6]
   If $strVendorSpecific[$i] = 3 Then $sT = $strVendorSpecific[$i] &'|'& $strVendorSpecific[$i + 1] &'|'& $strVendorSpecific[$i + 2] &'|'& $strVendorSpecific[$i + 3] &'|'& $strVendorSpecific[$i + 4] &'|'& $strVendorSpecific[$i + 5] &'|'& $strVendorSpecific[$i + 6]
   If $strVendorSpecific[$i] = 194 Then $sTemp = $strVendorSpecific[$i] &'|'& $strVendorSpecific[$i + 1] &'|'& $strVendorSpecific[$i + 2] &'|'& $strVendorSpecific[$i + 3] &'|'& $strVendorSpecific[$i + 4] &'|'& $strVendorSpecific[$i + 5] &'|'& $strVendorSpecific[$i + 6]

   If $strVendorSpecific[$i] = 231 Then $sTemp231 = $strVendorSpecific[$i] &'|'& $strVendorSpecific[$i + 1] &'|'& $strVendorSpecific[$i + 2] &'|'& $strVendorSpecific[$i + 3] &'|'& $strVendorSpecific[$i + 4] &'|'& $strVendorSpecific[$i + 5] &'|'& $strVendorSpecific[$i + 6]

         Next

         _ArrayAdd($Smart, $sPark)
         _ArrayAdd($Smart, $sP)
         _ArrayAdd($Smart, $sT)
         _ArrayAdd($Smart, $sTemp)
         _ArrayAdd($Smart, $sTemp231) ; Это обычно пустое значение для проверки
         _ArrayDisplay($Smart, 'Smart', Default, '', Default, "ID|Attribute|Type|Flag|Threshold|Value|Worst|Status")

Где и на каком этапе и как более правильно отсекать такие строки (переменные)?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
перед добавлением в массив проверить строку на наличие данных. да, это дополнительная писанина, но если хотим чтобы было все хорошо, то нужно описывать все возможные события
Код:
StringStripWS

эта функция удаляет пробелы. обрабатываем этой функцией строку и если после этого строка не ровна пустому значению, тогда добавляем ее в массив
 
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
перед добавлением в массив проверить строку на наличие данных
Добавил вот так
Код:
For $i = 1 To 8
   StringStripWS($sPark, $i)
Next
If $sPark <> 0 Then _ArrayAdd($Smart, $sPark)
         _ArrayAdd($Smart, $sP) ; тут пока не стал делать проверку, двух пока хватит
         _ArrayAdd($Smart, $sT)
         _ArrayAdd($Smart, $sTemp)
For $i = 1 To 8
   StringStripWS($sTemp231, $i)
Next
If $sTemp231 Then _ArrayAdd($Smart, $sTemp231)
         _ArrayDisplay($Smart, 'Smart', Default, '', Default, "ID|Attribute|Type|Flag|Threshold|Value|Worst|Status")

Работает, но писанины и правда много.
да, это дополнительная писанина, но если хотим чтобы было все хорошо, то нужно описывать все возможные события
Можно как-то такую запись сократить? Или я не правильно стал делать проверку?
Сообщение автоматически объединено:

Ещё проявилась одна проблема с проверкой. Ругается, что не все переменные объявлены. Как такую проверку пройти?
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
в функции удаления пробелов второй параметр поставь тройку или восьмерку. смотри описание функции
переменные всегда объявляй. локальная она или глобальная. это очень полезная привычка
знак == используется для строк. точное сравнение с учетом регистра. для чисел это не нужно(смотри в справке "операторы")
пример с твоим кодом
Код:
#include <Constants.au3>
#include <Array.au3>
Opt("MustDeclareVars", 1)
Const $wbemFlagReturnImmediately = 0x10
Const $wbemFlagForwardOnly = 0x20
Global $Smart[0][8]
Global $sTemp, $sTemp231, $sTemp1
Local $sPark, $sP, $sT
Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\WMI")
Local $colItems = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_ATAPISmartData", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
Local $iCnt = 1, $strReserved, $strVendorSpecific
For $Item In $colItems
    $strReserved = $Item.Reserved
    $strVendorSpecific = $Item.VendorSpecific
    $iCnt += 1
Next
For $i = 2 To UBound($strVendorSpecific) - 1 Step 12
    If $strVendorSpecific[$i] = 0 Then ContinueLoop
    If $strVendorSpecific[$i] = 1 Then $sPark = $strVendorSpecific[$i] & '|' & $strVendorSpecific[$i + 1] & '|' & $strVendorSpecific[$i + 2] & '|' & $strVendorSpecific[$i + 3] & '|' & $strVendorSpecific[$i + 4] & '|' & $strVendorSpecific[$i + 5] & '|' & $strVendorSpecific[$i + 6]
    If $strVendorSpecific[$i] = 2 Then $sP = $strVendorSpecific[$i] & '|' & $strVendorSpecific[$i + 1] & '|' & $strVendorSpecific[$i + 2] & '|' & $strVendorSpecific[$i + 3] & '|' & $strVendorSpecific[$i + 4] & '|' & $strVendorSpecific[$i + 5] & '|' & $strVendorSpecific[$i + 6]
    If $strVendorSpecific[$i] = 3 Then $sT = $strVendorSpecific[$i] & '|' & $strVendorSpecific[$i + 1] & '|' & $strVendorSpecific[$i + 2] & '|' & $strVendorSpecific[$i + 3] & '|' & $strVendorSpecific[$i + 4] & '|' & $strVendorSpecific[$i + 5] & '|' & $strVendorSpecific[$i + 6]
    If $strVendorSpecific[$i] = 194 Then $sTemp = $strVendorSpecific[$i] & '|' & $strVendorSpecific[$i + 1] & '|' & $strVendorSpecific[$i + 2] & '|' & $strVendorSpecific[$i + 3] & '|' & $strVendorSpecific[$i + 4] & '|' & $strVendorSpecific[$i + 5] & '|' & $strVendorSpecific[$i + 6]
    If $strVendorSpecific[$i] = 231 Then $sTemp231 = $strVendorSpecific[$i] & '|' & $strVendorSpecific[$i + 1] & '|' & $strVendorSpecific[$i + 2] & '|' & $strVendorSpecific[$i + 3] & '|' & $strVendorSpecific[$i + 4] & '|' & $strVendorSpecific[$i + 5] & '|' & $strVendorSpecific[$i + 6]
Next

If StringStripWS($sPark, 8) <> '' Then _ArrayAdd($Smart, $sPark)
If StringStripWS($sP, 8) <> '' Then _ArrayAdd($Smart, $sP)
If StringStripWS($sT, 8) <> '' Then _ArrayAdd($Smart, $sT)
If StringStripWS($sTemp, 8) <> '' Then _ArrayAdd($Smart, $sTemp)
If StringStripWS($sTemp231, 8) <> '' Then _ArrayAdd($Smart, $sTemp231) ; Это обычно пустое значение для проверки
_ArrayDisplay($Smart, 'Smart', Default, '', Default, "ID|Attribute|Type|Flag|Threshold|Value|Worst|Status")
насчет краткости. то это не всегда хорошо. ибо многие функции возвращают ошибки и их нужно проверять. не до фанатизма, конечно.
используй отдельные функции с параметрами и без. глобальные переменные объявляй по необходимости. остальные объявляй как локальные, в функциях. функция отработала и память освободилась.

насчет корректности кода. я не знаю какие цели ты преследуешь. каков глобальный замысел. это ведь часть кода программы.
если вернуться к проверке пустых строк, то можно не делать этого. пусть будут пустые. так ты избежишь лишней писанины. если страдаешь максимализмом, тогда нет предела совершенству ))
 
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
в функции удаления пробелов второй параметр поставь тройку или восьмерку
Я так понял, что 8 лучше, потому и использовал её, но твой вариант круче )
переменные всегда объявляй
Да уж, если их объявлять, то только в этом списке их будет порядка 50 ))) Думаю, как лучше: запихнуть их в массив, или присвоить одно длинное значение и делить в значении переменной разделителем, вытаскивая части.
функция отработала и память освободилась
Потому и думаю как запихнуть в массив или в одно значение
ибо многие функции возвращают ошибки и их нужно проверять.
Ну так и проверять ошибки. Все короче будет. Ато завтра производитель придумает ещё параметр в смарте и пиши допстроку.
пусть будут пустые. так ты избежишь лишней писанины
Не люблю лишнее в резльтате. Когда код чего-то делает - ты не видишь. А результат видишь, и пустые строки будут мельтешить
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
да, переменных может быть много. 50 это малое количество))
чтобы не придумывать новые длинные имена, нужно составлять свои функции, в которых будут локальные переменные. Имена этих переменных можно использовать и в других функциях.
 
Верх