Что нового

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

DyadyaGenya

Новичок
Сообщения
106
Репутация
0
Добрый день. Получаю кучу всяких смарт данных винчестера и слаживаю их в массив. Зарезервированных значений много. Но не все используются различными производителями, поэтому массив каждый раз разный по размеру, и ложить пустую строку (пустое значение переменной) в массив не хочется. Делаю так:
Код:
#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 350
Репутация
576
перед добавлением в массив проверить строку на наличие данных. да, это дополнительная писанина, но если хотим чтобы было все хорошо, то нужно описывать все возможные события
Код:
StringStripWS

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

DyadyaGenya

Новичок
Сообщения
106
Репутация
0
перед добавлением в массив проверить строку на наличие данных
Добавил вот так
Код:
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 350
Репутация
576
в функции удаления пробелов второй параметр поставь тройку или восьмерку. смотри описание функции
переменные всегда объявляй. локальная она или глобальная. это очень полезная привычка
знак == используется для строк. точное сравнение с учетом регистра. для чисел это не нужно(смотри в справке "операторы")
пример с твоим кодом
Код:
#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

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

joiner

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