bitshadow Posted March 4, 2008 Share Posted March 4, 2008 hi y'all. this might not be the best alogrithm to do this and there might be a more succint way of doing this. however i have the following funcitonexpandcollapse popupFunc LoadFile($fp,$nums) ;create an array of records so we can have each number in the struct how to make it global? Dim $RECORD[$nums] ;what line we on $recordNum=0 ;what phone digit we on $phoneDigit=0 ;create an array of valid numbers Dim $VALIDNUMS[10] for $ndx = 0 to 9 $VALIDNUMS[$ndx] = $ndx ;MsgBox(0,"Valid Number Init ", $VALIDNUMS[$ndx]) Next ;create and initialize an array of structs of recordnum size For $record_num = 0 to $nums-1 $RECORD[$record_num] = doopsCreateStruct() Next ;copy every character from the file to a record EX: RECORD[line_num].phoneNum[digit] = num While 1 ;read in 1 character at a time from the file till EOF $char = FileRead($fp,1) ;if its the EOF If @error = -1 Then ExitLoop ;check if number is a valid digit only put in the numbers For $x = 0 to 9 ;only add the valid digits If $char = $VALIDNUMS[$x] Then ;add the character to the phone number: read RECORD[num].phoneNumber[digit] = "number" DllStructSetData($RECORD[$recordNum],$phoneNum[$phoneDigit],$char) MsgBox(0,$VERSION,"CHARACTER INPUTED: " & $char) ;advance to next phone digit to check $phoneDigit+=1 EndIf Next; check against the next number If @CRLF Then MsgBox(0,$VERSION,$phoneNum[0]) ;reset the phone number sequence $phoneNum[$phoneDigit] = 0 ;go to the next record $recordNum+=1 EndIf MsgBox(0,$VERSION, "ERROR: " & @error & " reading char: " &$char) WEnd MsgBox(0,$VERSION,"DONE ALLOCATING PHONE NUMBERS TO STRUCTS") EndFunc it iterates through the file given as an argument and reads character by character allocating its contents to a array of structs. for some reason though i dont seem to be reading in any characters. i know its someting in my while loop. can someone tell me whats going on. thank you. Link to comment Share on other sites More sharing options...
weaponx Posted March 4, 2008 Share Posted March 4, 2008 doopsCreateStruct() function is missing. Link to comment Share on other sites More sharing options...
Siao Posted March 4, 2008 Share Posted March 4, 2008 (edited) FileRead a file in a loop one char at a time is a horrible idea from performance, efficience, sanity and any other standpoint. Other ideas, such as checking if a char is numerical by running it through a "For $x = 0 To 9" loop and even having a special array for that, are pretty whacky too. Forget about the question why it doesn't seem to be reading any characters, just rewrite everything from scratch, and don't forget to refer to the helpfile while doing it, you might find a lot of interesting stuff in there, such as StringIsDigit(), StringMid(), StringSplit(), StringRegExp(), and so on. Edited March 4, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
bitshadow Posted March 4, 2008 Author Share Posted March 4, 2008 FileRead a file in a loop one char at a time is a horrible idea from performance, efficience, sanity and any other standpoint. Other ideas, such as checking if a char is numerical by running it through a "For $x = 0 To 9" loop and even having a special array for that, are pretty whacky too.Forget about the question why it doesn't seem to be reading any characters, just rewrite everything from scratch, and don't forget to refer to the helpfile while doing it, you might find a lot of interesting stuff in there, such as StringIsDigit(), StringMid(), StringSplit(), StringRegExp(), and so on.i appreciate the replies guys and i'll be sure to "refactor" when i get a chance, what i would like to know now though is the cause of the problem.the doopsCreateStruct() seems to be working fine - at least its allocating. its late where i'm at but what does that have to do with not capturing from the file?thanks for your replies. Link to comment Share on other sites More sharing options...
weaponx Posted March 4, 2008 Share Posted March 4, 2008 It's bad practice to use variables named so similar: $recordNum and $record_num It's also smarter to use something like _FileReadToArray() to get the file into your program. StringRegExp() can quickly format phone numbers in one line rather than looping through every possible digit for each character in the string. We can't debug without seeing the code for doopsCreateStruct() and an example portion of your text file. Link to comment Share on other sites More sharing options...
bitshadow Posted March 4, 2008 Author Share Posted March 4, 2008 We can't debug without seeing the code for doopsCreateStruct() and an example portion of your text file. Thanks for your replies guys and excuse my autoit ignorance. i just picked it up a couple days ago. the text file is just a list of phone numbers formatted like so:1234567890 (123) 456 7890 456 7899093 the doopscreateStruct() is as follows. i'm coiming from a c background, so i'm sure "i'm still thinking in C"Func doopsCreateStruct() #cs the ideal situation as in c - would be to do this: typedef struct{ char flag char phoneNum[$DIGITS] }doops_t then allocate an array of structs like so: doops_t records[NUM_OF_RECORDS] and call like so: while !EOF: records[NUM].phone_number[digit] = "digit" record[NUM].flag = "flag" however seems autoitv3 doesn't allow array of structs so the workaround: #ce ;struct members can't have "variable_name", contstants in the array, no 2D arrays and no arrays of struts? $vars ="char flag ;char phoneNum[14]" ;create doops_t structure $record = DllStructCreate($vars) if @error Then MsgBox(0,$VERSION,"unable to create structure ERROR: " &@error) Else ;MsgBox(0,$VERSION, "STRUCT CREATED SUCCESFULLY SIZEOF STRUCT: " & DllStructGetSize($record) & " bytes") EndIf Return $record EndFunc Link to comment Share on other sites More sharing options...
weaponx Posted March 4, 2008 Share Posted March 4, 2008 (edited) Take a look at this.#include <File.au3> Dim $fileArray $fileName = "phone.txt" ;Read file to array _FileReadToArray($fileName, $fileArray) ;Loop through all array elements For $X = 1 to $fileArray[0] ;Ignore blank lines in the file If $fileArray[$X] <> "" Then ;Strip all non-numeric characters from string $result = StringRegExpReplace($fileArray[$X], "\D", "") ConsoleWrite("Before: " & $fileArray[$X] & " After: " & $result & @CRLF) If StringLen($result) = 11 Then ;Country code is present $resultFormat = StringRegExpReplace($result,"(\d{1})(\d{3})(\d{3})(\d{4})","$1 ($2) $3-$4") ConsoleWrite("Formatted: " & $resultFormat & @CRLF) ElseIf StringLen($result) = 10 Then ;Country code not present $resultFormat = StringRegExpReplace($result,"(\d{3})(\d{3})(\d{4})","($1) $2-$3") ConsoleWrite("Formatted: " & $resultFormat & @CRLF) Else ;Phone number invalid ConsoleWrite("Invalid number: " & $fileArray[$X] & @CRLF) EndIf ConsoleWrite(@CRLF) EndIf Nextphone.txt:CODE1-(419)-555-12341-419-555-1234141955512341.419.555.1234(419)-555-1234419-555-12344195551234419.555.1234Console output:CODEBefore: 1-(419)-555-1234 After: 14195551234Formatted: 1 (419) 555-1234Before: 1-419-555-1234 After: 14195551234Formatted: 1 (419) 555-1234Before: 14195551234 After: 14195551234Formatted: 1 (419) 555-1234Before: 1.419.555.1234 After: 14195551234Formatted: 1 (419) 555-1234Before: (419)-555-1234 After: 4195551234Formatted: (419) 555-1234Before: 419-555-1234 After: 4195551234Formatted: (419) 555-1234Before: 4195551234 After: 4195551234Formatted: (419) 555-1234Before: 419.555.1234 After: 4195551234Formatted: (419) 555-1234EDIT: Kicked code up a notch Edited March 4, 2008 by weaponx Link to comment Share on other sites More sharing options...
bitshadow Posted March 4, 2008 Author Share Posted March 4, 2008 a cursory glance says you obviously have more experience with autoit. i see some regualr expressions in there and some string functions and of course familiarity with some module i don't know about yet. i'll check it out, however i do want to figure out what the logic error is in my code, otherwise i won't learn anything and i'll just have it done for me. i've amalgamated my code into one function here. its supposed to take the contents of a file with phone numbers, put it in a array of structs so i can operate on them. however, my while loop seems to be executing prematurely and i'd like to know whats up. any help would be appreciated.expandcollapse popupFunc LoadLeadFile($fp,$nums) #cs the ideal situation as in c - would be to do this: typedef struct{ char flag char phoneNum[$DIGITS] }doops_t then allocate an array of structs like so: doops_t records[NUM_OF_RECORDS] and call like so: while !EOF: records[NUM].phone_number[digit] = "digit" record[NUM].flag = "flag" #ce ;struct members can't have "variable_name" $vars ="char flag ;char phoneNum[14]" ;create an array to hold records so we can have each number in the struct Dim $RECORD[$nums] ;initialize an array of structs of recordnum size For $structNum = 0 to $nums-1 $RECORD[$structNum] = DllStructCreate($vars) if @error Then MsgBox(0,$VERSION,"UNABLE TO CREATE STRUCT " & $structNum & " ERROR: " &@error) Else MsgBox(0,$VERSION, "STRUCT " & $structNum & " CREATED SUCCESFULLY " & @CRLF & _ "SIZEOF STRUCT: " & DllStructGetSize($RECORD[$structNum]) & " bytes") EndIf Next ;create and initialize an array of valid numbers Dim $validNum[10] for $ndx = 0 to 9 $validNum[$ndx] = $ndx MsgBox(0,"Valid Number Init ", $validNum[$ndx]) Next ;current record $recordNum=0 ;current phone digit we on $phoneDigit=0 ;copy every character from the file to a record EX: RECORD[line_num].phoneNum[digit] = num ;while loop isn't executing seems to reach EOF quick then exits can we rewind file? While 1 ;read in 1 character at a time from the file till EOF ;this is reading till eof without branching $char = FileRead($fp,1) ;if its the EOF If @error = -1 Then ExitLoop Else MsgBox(0, "Char read:", $char) EndIf ;check if number is a valid digit only put in the numbers For $x = 0 to 9 ;only add the valid digits doesn't seem to be case sensitive If $char = $validNum[$x] Then ;add the character to the phone number: read RECORD[num].phoneNumber[digit] = "number" DllStructSetData($RECORD[$recordNum], "phoneNum[$phoneDigit]",$char) ;advance to next phone digit to check $phoneDigit+=1 EndIf Next; check against the next number If @CRLF Then ;reset the phone number sequence $phoneDigit = 0 ;go to the next record $recordNum+=1 EndIf WEnd MsgBox(0,$VERSION,"EOF REACHED: " & @error) EndFunc Link to comment Share on other sites More sharing options...
weaponx Posted March 4, 2008 Share Posted March 4, 2008 (edited) I think you are defeating the purpose of using AutoIt. Embrace the ease of use. You are trying to bend the DllStruct* functions into Struct-like objects which only leads to frustration. Use a 2-dimensional array instead. EDIT: Also what is this ??? "If @CRLF Then" Another EDIT: It appears you are trying to use FileRead to get one character at a time when in reality you are getting an entire line at a time. Using $myfile = FileOpen("mytext.txt") and FileRead($myfile, 1) will read in one line at a time, just calling FileRead("mytext.txt", 1) will always read in the first character in the file... Edited March 4, 2008 by weaponx Link to comment Share on other sites More sharing options...
PsaltyDS Posted March 4, 2008 Share Posted March 4, 2008 a cursory glance says you obviously have more experience with autoit. i see some regualr expressions in there and some string functions and of course familiarity with some module i don't know about yet. i'll check it out, however i do want to figure out what the logic error is in my code, otherwise i won't learn anything and i'll just have it done for me. i've amalgamated my code into one function here. its supposed to take the contents of a file with phone numbers, put it in a array of structs so i can operate on them. however, my while loop seems to be executing prematurely and i'd like to know whats up. any help would be appreciated. You seem to be ignoring the answer to your question. You have already been told that you can't FileRead() in a loop with a literal file path instead of a handle. Run this, and you will see that it never moves past the first character: $sFile = "C:\Boot.ini" While 1 $char = FileRead($sFile, 1) If @error Then ExitLoop ConsoleWrite("Debug: $char = " & $char & @LF) WEndoÝ÷ ØZ)âé²¢ì"YÞyÛh)^:§jwlj÷èZÙ^mçèëazZ(¦Ø^붡jweyú+¶Wy§l{"uëazZ(¥«¢+ØÀÌØíÍ¥±ôÅÕ½ÐíèÀäÈí ½½Ð¹¥¹¤ÅÕ½Ðì(ÀÌØí¡¥±ô¥±=Á¸ ÀÌØíÍ¥±°À¤)]¡¥±Ä($ÀÌØí¡Èô¥±I ÀÌØí¡¥±°Ä¤(%%ÉɽÈQ¡¸á¥Ñ1½½À(% ½¹Í½±]É¥Ñ ÅÕ½ÐíÕèÀÌØí¡ÈôÅÕ½ÐìµÀìÀÌØí¡ÈµÀì1¤)]¹)¥± ±½Í ÀÌØí¡¥±¤ Get the Vista out of your ears... Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
bitshadow Posted March 5, 2008 Author Share Posted March 5, 2008 Thank you all so much that answers my question as to what was going on. correct me if i'm wrong but a windows "handle" is basically a pointer right? you seem to be ignoring the answer to your question. You have already been told that you can't FileRead() in a loop with a literal file path instead of a handle. Run this, and you will see that it never moves past the first character: Psalty Ds, thanks for your code illustrating what you said. i thought i understood that and thought i was passing a handle to the LoadLead() function. thus : $fp == file pointer. the file handle was supposed to be returned from this function Func OpenFile() $file_name = FileOpenDialog($VERSION,@DesktopCommonDir,"(*txt)","","File Name") ; if file was opened unsucessfully if @error = 1 Then MsgBox(0,"","uanble to get file path try again") Exit EndIf ;open the file for reading $fp = FileOpen($file_name,0) ;Check if file opened for reading OK If $fp = -1 Then MsgBox(0, "Error", "Unable to open file.") Exit EndIf ;return "file handle" that is the pointer to the file return $fp EndFuncoÝ÷ Ú+pjÇWyybë(jëh×6;retrieve the file pointer to open returns a pointer to the file $filep = OpenFile()oÝ÷ ٩ݶ§¥«,yÛh¶¡§Ky§EW¥G¬¡«¢+Ù1½1¥± ÀÌØí¥±À°ÀÌØí¹ÕµÌ where $nums was the num of lines in the file. i obvioulsy did not return a file handle. how can i do that or can't i - without opening the file in the LoadLeadFile scope? Having said all that weapon x thank you for your example usage of _fileReadToArray. i've checked the _file.au3 include file as well and found a boon of functions to do what i want. its obviously a more "autoit" way of accomplishing what i want and i was sure i'd find out later, but for now i have "C" in my ears - not Vista. Link to comment Share on other sites More sharing options...
PsaltyDS Posted March 5, 2008 Share Posted March 5, 2008 That method should work. You got the file handle in OpenFile(), returned it to the $filep variable, and then passed that to LoadLeadFile(). The 1-byte FileRead loop in that function should work with a file handle. I didn't see you say that $fp was a file handle, and when I read your code, $fp looked like "file path" string to me, but I shouldn't have made that assumption. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
bitshadow Posted March 5, 2008 Author Share Posted March 5, 2008 (edited) That method should work. You got the file handle in OpenFile(), returned it to the $filep variable, and then passed that to LoadLeadFile(). The 1-byte FileRead loop in that function should work with a file handle. I didn't see you say that $fp was a file handle, and when I read your code, $fp looked like "file path" string to me, but I shouldn't have made that assumption. and yet on entering LoadLeadFile() EOF is obviously reached. i'm actually stumped so i'm posting the full code, you can use any text file. i will obviously recode it with the functions in the file.au3 module with the help of some string functions, however this will irk me to no end. any help is appreciated. expandcollapse popup#cs ---------------------------------------------------------------------------- Author: bitshadow function: reads a file and allocates to a struct for processing #ce ---------------------------------------------------------------------------- ;explicity let us know these are global variables Global $DIGITS = 30 Global $VERSION = "1.0" Global $PNUMBERS = 10 ;retrieve the file pointer to open returns a pointer to the file $filep = OpenFile() ;get the number of records in the file $nums = NumOfRecs($filep); ;allocate records to struct so can compare them easily and write back to file LoadLeadfile($filep,$nums) Func OpenFile() ;first we'll use a FileOpenDialog then later we'll add the gui with GUICtrlCreateInput ;FileOpenDialog allows you one way to CHOOSE your file instead of typing it autoit has no STDIN or its redirected elsewhere ;it returns the full path of the file chosen - Not the actual pointer to the file - sets @error to 1 on failure ;Window title, start directory, type of file,options (see options), default name $file_name = FileOpenDialog($VERSION,@DesktopCommonDir,"(*txt)","","File Name") ; if file was opened unsucessfully if @error = 1 Then MsgBox(0,"","uanble to get file path") Exit EndIf ;open the file for reading: assumes it goes to that path and actually opens the File ;and returns a pointer in windows a HWND a "smart pointer" $fp = FileOpen($file_name,0) ;Check if file opened for reading OK If $fp = -1 Then MsgBox(0, "Error", "Unable to open file.") Exit EndIf ;return "file handle" to the file return $fp EndFunc Func NumOfRecs($fp) ;has a pointer to the file so just go there and read it ;num of records in file first line it reads is 1 not zero Local $num=1 ;iterate through the file and read how many new lines this indicates number of phone numbers ;Read in lines of text until the EOF is reached check out _FileCountLines later While 1 ;returns the line it read $line = FileReadLine($fp) ;ConsoleWrite("line number: " & $num & " " & $line & @LF) ;keep track of how many lines read $num+=1 ;if we reach the EOF then break If @error = -1 Then ExitLoop Wend MsgBox(0,$VERSION,"there are " & $num & " Records in the file") ;FileClose($fp);is this why we keep reaching the eof. its still opened and we're at the end so @error ==1 thus ;when called in loadlead file its still at -1 and thus end of file if we close it where is @error Then ;maybe we should have each function returns its own value and not put it on @error or SetError(0) again? ;as per documentation when entering a funtion @error is always set to 0 Return $num EndFunc Func LoadLeadFile($fp,$nums) #cs the ideal situation as in c - would be to do this: typedef struct{ char flag char phoneNum[$DIGITS] }doops_t then allocate an array of structs like so: RECORD record[NUM_OF_RECORDS] and call like so: while !EOF: record[NUM].phone_number[digit] = "digit" record[NUM].flag = "flag" use _FileReadToArray to strip contents of text file of '\n' and put each line in a array with each element being a line. so basically Autoit's version of what C does - kinda #ce ;struct members can't have "variable_name" seemingly autoit thinking its a string? $vars ="char flag;char phoneNum[14]" ;declare an array of stucts to hold each record Dim $RECORD[$nums] ;create an array of structs to hold each record For $structNum = 0 to $nums-1 $RECORD[$structNum] = DllStructCreate($vars) if @error Then MsgBox(0,$VERSION,"UNABLE TO CREATE STRUCT " & $structNum & " ERROR: " &@error) Exit Else ;MsgBox(0,$VERSION, "STRUCT " & $structNum & " CREATED SUCCESFULLY " & @CRLF & _ ;"SIZEOF STRUCT: " & DllStructGetSize($RECORD[$structNum]) & " bytes") EndIf Next ;create and initialize an array of valid numbers Dim $validNum[$PNUMBERS] for $ndx = 0 to 9 $validNum[$ndx] = $ndx ;MsgBox(0,"Valid Number Init ", $validNum[$ndx]) Next ;current record $recordNum = 1 ;current phone digit we on $phoneDigit = 0 ;copy every character from the file to a record EX: RECORD[line_num].phoneNum[digit] = num ;while loop seems to reach EOF when first time loop starts then exits can we rewind file. While 1 ;read in 1 character at a time from the file till EOF ;this is reading till eof without branching $char = FileRead($fp,1) ;if its the EOF it'll be -1 thus not 0 thus not true If @error Then ExitLoop Else ConsoleWrite("line number: " & $recordNum & " " & $char & @LF) ;MsgBox(0, "Char read: ", $char) EndIf ;check if number is a valid digit only put in the numbers For $x = 0 to 9 ;only add the valid digits doesn't seem to be case sensitive If $char = $validNum[$x] Then ;add the character to the phone number: read RECORD[num].phoneNumber[digit] = "number" DllStructSetData($RECORD[$recordNum], "phoneNum[$phoneDigit]",$char) ;advance to next phone digit to check $phoneDigit+=1 EndIf Next; check against the next number If $char = @LF Then ;reset the phone number sequence $phoneDigit = 0 ;go to the next record $recordNum+=1 EndIf WEnd MsgBox(0,$VERSION,"EOF REACHED: " & @error) EndFunc Edited March 6, 2008 by bitshadow Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now