Jump to content

Comparing a line of random characters with a text from a file + write to a files


Recommended Posts

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

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.

#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

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

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

I can't edit my above post so I have to write a new one.

I changed a little your script.

#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

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.

#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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...