goldsztrom Posted August 21, 2010 Share Posted August 21, 2010 Hi, What I (my script) intend to do is the following: 1. Open a file "file.txt" 2. Generate a random line of characters (letters), something like "hjniecvuniasibmap" 3. Check if the line generated isn't already present in the file "file.txt" 4. Check if the line generated isn't present in the another file "file2.txt" 5. If it is present, then generate again a line and check again if it is present etc... 6. If it is not present, then write this line to the file "file.txt" 7. Repeat this actions 128 times (Write 128 - or any other number - lines and make sure every line is unique) 8. And finally read line by line from the file "file.txt" and send it line by line to the file "file2.txt" until the last line What seems most difficult for me is the fact that I have to work with two open files ("file.txt" and "file2.txt) simultanously. Moreover, I have to work with the file "file.txt" and performg two different operations on the same file (that is, to read from this file and then to write to this file; to compare if there are two the same lines in this file). The example structure of the both files "file.txt" and "file2.txt": djgjsdfgj vbcnbnbnc czuxiuixc copzxoppp cxxycygxy This is my try (which failed). Local Const $file = "file.txt" Local Const $file2 = "file2.txt" Local $counter2 = 1 Do Local $texttowrite = "n" ; text starts with the 'n' letter Local $line = "" ; every time the loop repeats, this value is cleared FileOpen($file) FileReadLine($file, $line) FileClose($file) For $counter1 = 0 To 5 $texttowrite &= Chr(Random(97, 122, 1)) Next If $texttowrite = $line Then ExitLoop ; comparing FileOpen($file2, $line) FileReadLine($file2, $line) FileClose($file2) If $texttowrite = $line Then ExitLoop ; again comparing FileOpen($file,1) FileWriteLine($file, $texttowrite & @CRLF) FileClose($file) $counter2 = $counter2 + 1 Until $counter2 = 128 ; don't know how to read line by line "file.txt" and write line by line from it to "file2.txt" Someone helps me please. I'd be very grateful. Link to comment Share on other sites More sharing options...
Tvern Posted August 21, 2010 Share Posted August 21, 2010 I'm not sure I understand exactly what you want to do, but this might give you some idea's Instead of constantly re-reading file1 I'm using an array with the same contents as the file, which should work, as long as there isn't a 3rd party changing the files content. The example appends the new entries to whatever is currently in file1 and appends the entire content of file1 to what is already in file2. I wasn't sure what you wanted to do with existing data, but it's an easy change if you want it to behave otherwise. expandcollapse popup#include <array.au3> #include <file.au3> Local Const $sPath1 = @ScriptDir & "\file1.txt" Local Const $sPath2 = @ScriptDir & "\file2.txt" Local $aFile1, $aFile2, $hFile1, $hFile2 Local $sLine Local $NumLines = 128 ;specify the amount of lines here If _FileReadToArray($sPath1,$aFile1) <> 1 Then Local $aFile1[1] = [0] EndIf If _FileReadToArray($sPath2,$aFile2) <> 1 Then ;now you won't have to read the files anymore! Local $aFile2[1] = [0] EndIf ReDim $aFile1[$aFile1[0]+1+$NumLines] ;make room for the extra entries to avoid multiple (slow) redims #region Add specified number of unique entries to File1 $hFile1 = FileOpen($sPath1,1) For $i = 0 To $NumLines-1 ;repeat 128 times (or whatever you put for $Numlines Do $sLine = "n" ; text starts with the 'n' letter For $i0 = 0 To 5 $sLine &= Chr(Random(97, 122, 1)) Next Until (_ArraySearch($aFile1,$sLine,1) = -1) And (_ArraySearch($aFile2,$sLine,1) = -1) ;the string is unique! $aFile1[0] += 1 ;Update the index cound as UBound won't work anymore $aFile1[$aFile1[0]] = $sLine ;Add text to the array If FileWriteLine($hFile1,$sLine) <> 1 Then ConsoleWrite("Error" & @CRLF) ;Add text to the file one line at the time Next FileClose($hFile1) #endregion #region Add contents of File1 to File2 ;As $aFile1 should have the same content as the file, I would just write from the array, as it's much faster. $hFile2 = FileOpen($sPath2,1) For $i = 1 To $aFile1[0] FileWriteLine($hFile2,$aFile1[$i]) Next FileClose($hFile2) #endregion Keep in mind that it's probably still alot faster to write the files all at once, instead of line-by-line. Link to comment Share on other sites More sharing options...
goldsztrom Posted August 21, 2010 Author Share Posted August 21, 2010 Dear Tvern, thank you very much for your help.I know I failed to clearly explain what I want to do.I try to fo this in the easiest way I can. I want to create random strings (usernames) starting with a certain letters ("n" in this case). Then write this strings (usernames) to a file. Due to the fact that the function that generates random strings may generate accidentally the same strings (usernames) I need to check whether the all strings generated and written to the file are different. There cannot be two the same strings! I want to have a file with 128 (or any other number) unique strings (usernames). I want this file to be expanded whenever I run the scripts. It means the file must be check everytime the script runs in order to avoid same strings. After I generate all the strings I want them to be read line by line and send to another file (or a browser, or wherever I wish to send them).Is it clear? So if I undestand you correctly Tvern, I can't to this without using arrays. I thought it would be much easier to use a procedure to generate a random string, read a file line by line, check it whether any line of the file is the same with random string generated (if so, run the procedure again), and when it is not, then write this string to this file and perform this loop again until there are 128 (or any other number) strings. You suggested using an array but are you sure it is the best solution? Considering the fact that in another stage of the script the file will have to be read line by line (and send all the strings somewhere else), maybe this array idea isn't the most convenient.Sorry If I'm totally wrong. I realize I'm very new and don't understand a lot of AutoIt features (and the alghorithms). Link to comment Share on other sites More sharing options...
Tvern Posted August 21, 2010 Share Posted August 21, 2010 You don't have to use arrays, but it's allot more practical than reading the entire file for every string you want to add. The example I gave will ensure unique strings(line 26 takes care of that) and it does expand the file with a set number of strings. (You could also write it to expand to a set number of strings.) The file will be checked every time you run the script, but only once, instead of once for each string. If you want to send those strings to another application, like a browser, there is no need to read any file, as you still have the file's content in the array and you can use that directly. Ofcoarse if you want to save those strings untill the next time you run the program you will still have to write them to a file, but there is no reason to do so one line at the time. Instead you can just use _FileWriteFromArray(). As a rule of thumb it's best to keep the amount of read/write's to a minimum if you aim for performance. Link to comment Share on other sites More sharing options...
goldsztrom Posted August 21, 2010 Author Share Posted August 21, 2010 If _FileReadToArray($sPath1,$aFile1) <> 1 Then Local $aFile1[1] = [0] By the way, where I can find docs on functions such as _FileReadToArray? (I checked on the AutoIt official website but there is not docs). It seems this function is not a standard one. Thanks again. Link to comment Share on other sites More sharing options...
goldsztrom Posted August 22, 2010 Author Share Posted August 22, 2010 I can't edit my above post so I have to write a new one. I changed a little your script. expandcollapse popup#include <array.au3> #include <file.au3> Local Const $sPath1 = @ScriptDir & "\list.txt" Local $aFile1, $hFile1 Local $sLine, $tLine Local $NumLines = 128 ;specify the amount of lines here If _FileReadToArray($sPath1,$aFile1) <> 1 Then Local $aFile1[1] = [0] EndIf ReDim $aFile1[$aFile1[0]+1+$NumLines] ;make room for the extra entries to avoid multiple (slow) redims #region Add specified number of unique entries to File1 $hFile1 = FileOpen($sPath1,1) For $i = 0 To $NumLines-1 ;repeat 128 times (or whatever you put for $Numlines Do $sLine = "6" ; starts with "6" For $i0 = 0 To 8 $sLine &= Chr(Random(97, 122, 1)) Next Until (_ArraySearch($aFile1,$sLine,1) = -1) ;the string is unique! $aFile1[0] += 1 ;Update the index count as UBound won't work anymore $aFile1[$aFile1[0]] = $sLine ;Add text to the array If FileWriteLine($hFile1,$sLine) <> 1 Then ConsoleWrite("Error" & @CRLF) ;Add text to the file one line at the time Next FileClose($hFile1) #endregion $hFile1 = FileOpen($sPath1,1) For $i = 0 to $aFile1[0] $tLine = FileReadLine($hFile1) Run("notepad.exe") WinActivate("Untitled - Notepad") Send($tLine) Next FileClose($hFile1) Why it isn't working. It supposed to run Notepad and send there every line ($tLine) from the file ($aFile1). What's wrong? Link to comment Share on other sites More sharing options...
Tvern Posted August 22, 2010 Share Posted August 22, 2010 Why it isn't working. It supposed to run Notepad and send there every line ($tLine) from the file ($aFile1). What's wrong? There where a few errors in your script which I fixed and commented. Keep in mind that $aFile1 isn't a file, or handle to a file, but an array containing the files contents. So FileRead isn't needed. Also you might want to have a look at ControlSend, or ControlSetText to replace your Send. That way you can send text to the window even if it isn't focused, or even visible and you avoid text ending up in the wrong window. expandcollapse popup#include <array.au3> #include <file.au3> HotKeySet("{Esc}","_Exit") ;I found this to be usefull. Local Const $sPath1 = @ScriptDir & "\list.txt" Local $aFile1, $hFile1 Local $sLine, $tLine Local $NumLines = 128 ;specify the amount of lines here If _FileReadToArray($sPath1,$aFile1) <> 1 Then Local $aFile1[1] = [0] EndIf ReDim $aFile1[$aFile1[0]+1+$NumLines] #region Add specified number of unique entries to File1 $hFile1 = FileOpen($sPath1,1) For $i = 0 To $NumLines-1 Do $sLine = "6" ; starts with "6" For $i0 = 0 To 8 $sLine &= Chr(Random(97, 122, 1)) Next Until (_ArraySearch($aFile1,$sLine,1) = -1) ;the string is unique! $aFile1[0] += 1 $aFile1[$aFile1[0]] = $sLine If FileWriteLine($hFile1,$sLine) <> 1 Then ConsoleWrite("Error" & @CRLF) Next FileClose($hFile1) #endregion ;no need to open the file if you're writing from the array $PID = Run("notepad.exe") ;you only want to run it once, so leave it out of the loop. Also keep the Process ID for later use WinActivate($PID) ;Using the Process ID here is more reliable. Sleep(500) ;give the window some time to appear For $i = 1 to $aFile1[0] ;loop starts at one, as 0 has the number of lines in it. Send($aFile1[$i] & @CR) ;ControlSend would be allot better here. Next Func _Exit() Exit EndFunc 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