#2242 closed Bug (Fixed)
_FileWriteFromArray is incapable of writing only the zeroth element
Reported by: | BrewManNH | Owned by: | guinness |
---|---|---|---|
Milestone: | 3.3.9.5 | Component: | Standard UDFs |
Version: | 3.3.8.1 | Severity: | None |
Keywords: | Cc: |
Description
In the File.au3 UDF, the function _FileWriteFromArray can't be used to write only the zeroth [0] of an array due to the way it is written. It has the capability to write any other single element, such as [1] or [2], but you can't output to a file the first element.
There is a simple fix for it, but it would be a script breaking change if applied.
; <<< default value for $I_Ubound changed to -1 instead of 0 >>> Func _FileWriteFromArray($File, $a_Array, $i_Base = 0, $i_UBound = -1, $s_Delim = "|") ; Check if we have a valid array as input If Not IsArray($a_Array) Then Return SetError(2, 0, 0) Local $iDims = UBound($a_Array, 0) If $iDims > 2 Then Return SetError(4, 0, 0) ; determine last entry Local $last = UBound($a_Array) - 1 ; <<< This line changed to look for the value of $i_Ubound < 0 instead of $i_Ubound < 1 >>> If $i_UBound < 0 Or $i_UBound > $last Then $i_UBound = $last If $i_Base < 0 Or $i_Base > $last Then $i_Base = 0 ; Open output file for overwrite by default, or use input file handle if passed Local $hFile If IsString($File) Then $hFile = FileOpen($File, $FO_OVERWRITE) Else $hFile = $File EndIf If $hFile = -1 Then Return SetError(1, 0, 0) ; Write array data to file Local $ErrorSav = 0 Switch $iDims Case 1 For $x = $i_Base To $i_UBound If FileWrite($hFile, $a_Array[$x] & @CRLF) = 0 Then $ErrorSav = 3 ExitLoop EndIf Next Case 2 Local $s_Temp For $x = $i_Base To $i_UBound $s_Temp = $a_Array[$x][0] For $y = 1 To $iDims - 1 $s_Temp &= $s_Delim & $a_Array[$x][$y] Next If FileWrite($hFile, $s_Temp & @CRLF) = 0 Then $ErrorSav = 3 ExitLoop EndIf Next EndSwitch ; Close file only if specified by a string path If IsString($File) Then FileClose($hFile) ; Return results If $ErrorSav Then Return SetError($ErrorSav, 0, 0) Return 1 EndFunc ;==>_FileWriteFromArray
It's only 2 values in 2 lines that need to be changed, but would result in it being a script breaking change due to this.
Attachments (0)
Change History (8)
comment:1 Changed 12 years ago by trancexx
comment:2 Changed 12 years ago by BrewManNH
I'd have to agree on that as well, if this had been written correctly in the first place, 0 would never have meant the whole array because AutoIt arrays are 0 based, and not 1 based. It should probably be rewritten to use the Default keyword in the $i_Ubound parameter, but at least the way it's written above would allow you to write out only the first element of the array.
comment:3 Changed 12 years ago by Valik
This is really stupid. I expected this function to be written by some stupid dumbass... but nope, it was written by somebody who should have known better.
Anyway, this function is dumb and broken. Please re-write it correctly. All I ask is that you do not modify the function signature. Chances are people who are writing the entire array aren't even specifying 0 explicitly so if it's changed to Default it will only affect a very small number of people who are writing the entire array using a non-default delimiter. Or idiots who wrote bad code but I don't care about them.
comment:4 Changed 12 years ago by BrewManNH
Here's what I came up with for a fix. I've also added in another error code because the original function would take a start index that is greater than the end index as a valid input, it would convert it to 0 in that case. I changed it to an error condition.
; #FUNCTION# ==================================================================================================================== ; Name...........: _FileWriteFromArray ; Description ...: Writes Array records to the specified file. ; Syntax.........: _FileWriteFromArray($File, $a_Array[, $i_Base = 0[, $i_UBound = 0 [, $s_Delim= "|"]]) ; Parameters ....: $File - String path of the file to write to, or a file handle returned from FileOpen(). ; $a_Array - The array to be written to the file. ; $i_Base - Optional: Start Array index to read, normally set to 0 or 1. Default=0 ; $i_Ubound - Optional: Set to the last record you want to write to the File. default= whole array. ; $s_Delim - Optional: Delimiter character(s) for 2-dimension arrays. default="|" ; Return values .: Success - Returns a 1 ; Failure - Returns a 0 ; @Error - 0 = No error. ; |1 = Error opening specified file ; |2 = Input is not an Array ; |3 = Error writing to file ; |4 = Array dimensions > 2 ; |5 = $i_Base > $i_UBound ; Author ........: Jos van der Zande <jdeb at autoitscript dot com> ; Modified.......: Updated for file handles by PsaltyDS, @error = 4 msg and 2-dimension capability added by SPiff59 ; Remarks .......: If a string path is provided, the file is overwritten and closed. ; To use other write modes, like append or Unicode formats, open the file with FileOpen() first and pass the file handle instead. ; If a file handle is passed, the file will still be open after writing. ; Related .......: _FileReadToArray ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _FileWriteFromArray($File, $a_Array, $i_Base = Default, $i_UBound = Default, $s_Delim = "|") ; Check if we have a valid array as input If Not IsArray($a_Array) Then Return SetError(2, 0, 0) Local $iDims = UBound($a_Array, 0) If $iDims > 2 Then Return SetError(4, 0, 0) ; determine last entry Local $last = UBound($a_Array) - 1 If $i_UBound = Default Or $i_UBound > $last Then $i_UBound = $last ; determine last entry If $i_Base < 0 Or $i_Base = Default Then $i_Base = 0 ; new error condition if $i_Base > than $i_UBound If $i_Base > $i_UBound Then Return SetError(5, 0, 0) ; Open output file for overwrite by default, or use input file handle if passed Local $hFile If IsString($File) Then $hFile = FileOpen($File, $FO_OVERWRITE) Else $hFile = $File EndIf If $hFile = -1 Then Return SetError(1, 0, 0) ; Write array data to file Local $ErrorSav = 0 Switch $iDims Case 1 For $x = $i_Base To $i_UBound If FileWrite($hFile, $a_Array[$x] & @CRLF) = 0 Then $ErrorSav = 3 ExitLoop EndIf Next Case 2 Local $s_Temp For $x = $i_Base To $i_UBound $s_Temp = $a_Array[$x][0] For $y = 1 To $iDims - 1 $s_Temp &= $s_Delim & $a_Array[$x][$y] Next If FileWrite($hFile, $s_Temp & @CRLF) = 0 Then $ErrorSav = 3 ExitLoop EndIf Next EndSwitch ; Close file only if specified by a string path If IsString($File) Then FileClose($hFile) ; Return results If $ErrorSav Then Return SetError($ErrorSav, 0, 0) Return 1 EndFunc ;==>_FileWriteFromArray
comment:5 Changed 12 years ago by BrewManNH
I also came up with this as an alternative line
If $i_UBound = Default Or $i_UBound > $last Or $i_UBound < 0 Then $i_UBound = $last
This change would allow the use of -1 in the $i_UBound parameter to indicate the default parameter.
comment:6 Changed 12 years ago by trancexx
If you think or feel you need patronizer then maybe you shouldn't write that function.
I'm just saying. <-who says that? lol
comment:7 Changed 12 years ago by guinness
- Milestone set to 3.3.9.5
- Owner set to guinness
- Resolution set to Fixed
- Status changed from new to closed
Fixed by revision [7245] in version: 3.3.9.5
comment:8 Changed 12 years ago by guinness
The code above contains a bug that has been fixed in the latest beta when writing 2-dimensional arrays.
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
That's why Default keyword should be used instead of magic numbers/strings.