CLEO Help Question about file reading / counting

CLEO related
Status
Not open for further replies.

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,315
Solutions
7
Reaction score
935
Location
Lithuania
how can i find out how many lines a text file contains without viewing it in cleo?
Should return count of lines.
 

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,315
Solutions
7
Reaction score
935
Location
Lithuania
The point of this is i wanna read specific line and get text.

it should work like.:
GetChatEnteryText snippet
but for .txt file(s)
 

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,315
Solutions
7
Reaction score
935
Location
Lithuania
Code:
IF
0AAB:   file_exists "CLEO\C\C-Console.log"
then
    if
    8A9A: 30@ = openfile "CLEO\C\C-Console.log" mode "at"  // IF and SET
    then
        0@ = 0
        repeat
        wait 0
        0@ += 1
        until 0AD6:   end_of_file 30@ reached
              printf "Lines in file: %d" 1000 0@
 
        0A9B: closefile 30@
    end
end
What about if i wanna read file not from cleo , but from documents\samp it should work?
 
Last edited:

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,315
Solutions
7
Reaction score
935
Location
Lithuania
@monday
I found your old post , but when i tried use it with for 20@ = 0 to MAX_LINES it doesn't work...
Also how to get MAX_LINES ?

PHP:
{$CLEO .cs}
0000:


repeat
wait 50
until 0AFA:  SAMP_IS_READY

alloc 30@ 2000 // string from the new file
alloc 31@ 2000 // string from the last file

0@ = true

while true
wait 0
    if 0@ == true
    //if key_down 49
    then
    call @GetStringFromFile 2 stringPointer 30@ debug false // the string from file will be written to the memory at address 0@ (so there's no need for return)
        if 0C21: stricmp string1 30@ string2 31@
        then
        //do nothing if the same string was found
        else
        chatmsg "{FFFF00}%s" -1 30@
        0C13: strcpy destination 31@ source 30@ // copy string if the new one is found so it will be compared later
        end
    wait 700
    end
end

:GetStringFromFile
alloc 29@ 1000
0A9A: 31@ = openfile "CLEO/admin.txt" mode "rb" // IF and SET
0A9C: 30@ = file 31@ size
0C11: memset destination 0@ value 0 size 1000
    while 0AD7: read_string_from_file 31@ to 29@ size 30@ // it reads a single line from the file and returns false if the end of file was reached
    wait 0
  
  
    /*
    this "while" loop could be replaced with for example: "for 20@ = 0 to MAX_LINES" loop for each line in the file,
    then simple line checks could be used like:
  
    if 20@ == 0
    then
    //29@ = first line
    end
  
    if 20@ == 1
    then
    29@ = second line
    end
    */                                        
    0C15: strcat destination 0@ source 29@ // append single line (29@) to the main string (0@) which will include all the text within the file
    0C11: memset destination 29@ value 0 size 1000  // clear the line before reading the next one (just in case if 0AD7 isn't doing it automatically)
    end
//0A9D: readfile 31@ size 30@ to 0@ //(maybe it doesn't work with pointers - "If the number of delivered bytes is more than four, the remainder will be written to the next variable (2@ in this case), and so on.")
0A9B: closefile 31@
    if 1@ == true
    then
    chatmsg "File contains: %s" -1 0@
    end

free 29@
ret 0
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,127
Solutions
1
Reaction score
158
"rt" will open it in "read text" mode, "at" stands for "append text" maybe that's why you got result equal to 1
This seems to work:
Code:
IF
0AAB:   file_exists "CLEO/test.txt"
then
    if
    0A9A: 30@ = openfile "CLEO/test.txt" mode "rt"  // IF and SET
    then
        0@ = 0
        alloc 31@ 5000
        
        while 0AD7: read_string_from_file 30@ to 31@ size 5000 // retrieves data from a file into a buffer until it encounters a new line
        wait 0
            0@ += 1
        end
        
        free 31@
        
        0AD1: show_formatted_text_highpriority "Lines in file: %d" 15000 0@
    
        0A9B: closefile 30@
    else
    0AD1: show_formatted_text_highpriority "Couldn't open the file" 15000
    end
else
0AD1: show_formatted_text_highpriority "File doesn't exist" 15000
end
 

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,315
Solutions
7
Reaction score
935
Location
Lithuania
"rt" will open it in "read text" mode, "at" stands for "append text" maybe that's why you got result equal to 1
This seems to work:
Code:
IF
0AAB:   file_exists "CLEO/test.txt"
then
    if
    0A9A: 30@ = openfile "CLEO/test.txt" mode "rt"  // IF and SET
    then
        0@ = 0
        alloc 31@ 5000
      
        while 0AD7: read_string_from_file 30@ to 31@ size 5000 // retrieves data from a file into a buffer until it encounters a new line
        wait 0
            0@ += 1
        end
      
        free 31@
      
        0AD1: show_formatted_text_highpriority "Lines in file: %d" 15000 0@
  
        0A9B: closefile 30@
    else
    0AD1: show_formatted_text_highpriority "Couldn't open the file" 15000
    end
else
0AD1: show_formatted_text_highpriority "File doesn't exist" 15000
end
Works, thx.
 
Last edited:

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,315
Solutions
7
Reaction score
935
Location
Lithuania
Probably this way best , to count how many lines are in file.
If i wanna get last line or one before last. like 98 or 99
PHP:
{$CLEO .cs}
0000:
wait 7000 

while true
wait 0

0AB1: @Counter 0 _ReturnTotalNumberOfLines 1@
0AB1: @Read_String_From_File 1 _ReadLine 1@ _ReturnText 3@
chatmsg "%s" -1 3@

end

:Read_String_From_File
IF
0AAB:   file_exists "CLEO/admin.txt"
then
    if
    0A9A: 30@ = openfile "CLEO/admin.txt" mode "rt"  // IF and SET
    then
        10@ = 0
        alloc 31@ 20000
            while 0AD7: read_string_from_file 30@ to 31@ size 20000 // retrieves data from a file into a buffer until it encounters a new line
            wait 0
                10@++
                if
                003B:   10@ == 0@  // (int)
                then
                    0AB2: 1 31@
                end
            end
        free 31@
        0A9B: closefile 30@
    else
        0AD1: show_formatted_text_highpriority "Couldn't open the file" 15000
    end
else
    0AD1: show_formatted_text_highpriority "File doesn't exist" 15000
end
0AB2: ret 0

:Counter
IF
0AAB:   file_exists "CLEO/admin.txt"
then
    if
    0A9A: 30@ = openfile "CLEO/admin.txt" mode "rt"  // IF and SET
    then
        10@ = 0
        alloc 31@ 20000
            while 0AD7: read_string_from_file 30@ to 31@ size 20000 // retrieves data from a file into a buffer until it encounters a new line
            wait 0
                10@++ // count
            end
        free 31@
        0AB2: ret 1 10@
        0A9B: closefile 30@
    else
        0AD1: show_formatted_text_highpriority "Couldn't open the file" 15000
    end
else
    0AD1: show_formatted_text_highpriority "File doesn't exist" 15000
end
0AB2: ret 0
 
Last edited:

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,315
Solutions
7
Reaction score
935
Location
Lithuania
Is there any way get every line nickname from .txt file without counting and doing for ?
@monday

PHP:
{$CLEO .cs}

0000:

REPEAT
WAIT 1000
0A8D: 0@ = readMem 0xA444A0 sz 4 vp 0
UNTIL 0@ == 1 // SAMP_IS_READY

while true
wait 0

0AB1: @Count_Lines 0 _ReturnTotalNumberOfLines 1@
for 2@ = 1 to 1@
    0AB1: @Read_String_From_File 1 _ReadLine 2@ _ReturnText 3@ // return nick name from ini file
    
    0AC8: 4@ = allocate_memory_size 145 // Chat alloc   
    0AB1: @GetChatEntryText 1 id 99 to 4@ // get last line chat text
    
    if                 
    0AB1: call_scm_func @IfTextContains 2 mainTextPointer 4@ pieceToFindPointer 3@ _returnedPointer 30@ //30@ is useless xDD
    then
        0AD1: "NickName was found!" 1000
    end 
    
    0AC9: free_allocated_memory 4@
end

end

:IfTextContains
{
    0@ - the main text
    1@ - piece of text to be found within the main text
}
0AB1: @StrLen 1 strPtr 0@ _length 31@
0AB1: @StrLen 1 strPtr 1@ _length 30@

//initial length check (the phrase can't be longer than the main text)
if 001D:   30@ > 31@  // (int)
then
    059A:  return_false
    0AB2: ret 1 0
end

31@ -= 1
26@ = 0 // counter of the same chars in a row
for 29@ = 0 to 31@ // for each char of the main text  (29@ = index)   
    0085: 24@ = 0@ // (int)
    005A: 24@ += 29@  // (int)
    0A8D: 28@ = read_memory 24@ size 1 virtual_protect 0
    
    0085: 23@ = 1@ // (int)
    005A: 23@ += 26@  // (int)
    0A8D: 27@ = read_memory 23@ size 1 virtual_protect 0

    if 003B:   28@ == 27@  // (int)   
    then
    26@++
        if 002D:   26@ >= 30@  // (int)
        then
            0485:  return_true
            0062: 24@ -= 30@  // (int)
            24@ += 1
            0AB2: ret 1 24@
        end
    else
        if 26@ > 0
        then
            29@-- //check the same char again and assume it's the begining of the string but only if there was matching parts before (otherwise it would go back all the time and make infinite loop)
        end
    26@ = 0
    end           
end
 
059A:  return_false
0AB2: ret 1 0

:strlen
{
    Example: 0AB1: @strlen 1 string 1@ return: 3@
    In: 0@ - text;
    Out: 1@ - size;
}
for 1@ = 0 to 1024
    0A8D: 2@ = read_memory 0@ size 1 virtual_protect 0
    if not 2@ == 0
    jf break
    0@ += 1
end
0AB2: ret 1 1@

:GetChatEntryText 
IF 0AA2: 1@ = "samp.dll"
THEN
    1@ += 0x21A0E4 // SAMP_CHAT_INFO_OFFSET_037
    0A8D: 1@ readMem 1@ sz 4 vp 0
    1@ += 0x132
    0@ *= 0xFC
    005A: 1@ += 0@
    1@ += 0x20
    0AA3: 1@
END
0AB2: ret 1 1@

:Read_String_From_File
IF
0AAB:   file_exists "CLEO/admin.txt"
then
    if
    0A9A: 30@ = openfile "CLEO/admin.txt" mode "rt"  // IF and SET
    then
        10@ = 0
        0AC8: 31@ = allocate_memory_size 20000
            while 0AD7: read_string_from_file 30@ to 31@ size 20000 // retrieves data from a file into a buffer until it encounters a new line
            wait 0
                10@ += 1
                if
                003B:   10@ == 0@  // (int)
                then
                    0AB2: 1 31@
                end
            end
        0AC9: free_allocated_memory 31@
        0A9B: closefile 30@
    else
        0AD1: show_formatted_text_highpriority "Couldn't open the file" 15000
    end
else
    0AD1: show_formatted_text_highpriority "File doesn't exist" 15000
end
0AB2: ret 0

:Count_Lines
IF
0AAB:   file_exists "CLEO/admin.txt"
then
    if
    0A9A: 30@ = openfile "CLEO/admin.txt" mode "rt"  // IF and SET
    then
        10@ = 0
        0AC8: 31@ = allocate_memory_size 20000
            while 0AD7: read_string_from_file 30@ to 31@ size 20000 // retrieves data from a file into a buffer until it encounters a new line
            wait 0
                10@ += 1 // count
            end
        0AC9: free_allocated_memory 31@
        0AB2: ret 1 10@
        0A9B: closefile 30@
    else
        0AD1: show_formatted_text_highpriority "Couldn't open the file" 15000
    end
else
    0AD1: show_formatted_text_highpriority "File doesn't exist" 15000
end
0AB2: ret 0
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,127
Solutions
1
Reaction score
158
Sorry but I don't understand the question. So the file contains names right? Each line has a single name I assume. Like:
Michal
Andrzej
Janusz
And you'd like to read (and print?) all the names but without using "for" loops?

Is that correct?

Edit: I think it would be good if you specified what goal are you trying to accomplish. Is the goal to store all of the names in memory to use them later?
 
Last edited:

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,315
Solutions
7
Reaction score
935
Location
Lithuania
Sorry but I don't understand the question. So the file contains names right? Each line has a single name I assume. Like:

And you'd like to read (and print?) all the names but without using "for" loops?

Is that correct?
Yes you are right, i trying get all nick names without for, i wanna make like admin checker.
Code should get nick name from .txt file and check from chat - exist or not.
With sf is like
PHP:
{
0@ - chat text
2@ - King_Lion // nick name from .txt file
}
If
0C29: $NOT_USED  str1 0@   str2 2@
Then
//..
End
 
Last edited:

monday

Expert
Joined
Jun 23, 2014
Messages
1,127
Solutions
1
Reaction score
158
you can just read the whole file like this I think:
Code:
0A9C: 1@ = file 0@ size // 0@ is received from "openfile" opcode
0085: 2@ = 1@
2@ += 1
alloc 3@ 2@  // alloc file size + 1
0A9D: readfile 0@ size 1@ to 3@

Then using strstr should work well for a text file, but keep in mind that if the file contained byte equal to 0 then the strstr would not reach the part of the file following the 0 byte.
 

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,315
Solutions
7
Reaction score
935
Location
Lithuania
you can just read the whole file like this I think:
Code:
0A9C: 1@ = file 0@ size // 0@ is received from "openfile" opcode
0085: 2@ = 1@
2@ += 1
alloc 3@ 2@  // alloc file size + 1
0A9D: readfile 0@ size 1@ to 3@

Then using strstr should work well for a text file, but keep in mind that if the file contained byte equal to 0 then the strstr would not reach the part of the file following the 0 byte.
Tested , retruning NULL and after 1-2min crash.
PHP:
{$CLEO .cs}

0000:

REPEAT
WAIT 1000
0A8D: 0@ = readMem 0xA444A0 sz 4 vp 0
UNTIL 0@ == 1 // SAMP_IS_READY

WHILE TRUE
WAIT 0

IF
10@ == FALSE
THEN
    IF
    0AAB:   file_exists "CLEO\admin.txt"
    THEN
        0A9A: 31@ = openfile "CLEO\admin.txt" mode "rt"  
        0A9C: 1@ = file 31@ size // 0@ is received from "openfile" opcode
        0085: 2@ = 1@
        2@ += 1
        0AC8: 3@ = allocate_memory_size 2@                  
        0A9D: readfile 31@ size 3@ to 4@
        0AD1: "%s" 1337 4@
    END
END

END
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,127
Solutions
1
Reaction score
158
It looks like you didn't copy it properly

0AC8: 3@ = allocate_memory_size 2@
0A9D: readfile 31@ size 3@ to 4@

In this part the size parameter is incorrect, it should be the size of the file (1@ returned from 0A9C), the destination should be the pointer to allocated memory (3@), so:
0A9D: readfile 31@ size 1@ to 3@
 

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,315
Solutions
7
Reaction score
935
Location
Lithuania
It looks like you didn't copy it properly



In this part the size parameter is incorrect, it should be the size of the file (1@ returned from 0A9C), the destination should be the pointer to allocated memory (3@), so:
0A9D: readfile 31@ size 1@ to 3@
Same crash.

Also i tested this one , this showing all nicknames , bet when i change it to ret i get only one nickname.
PHP:
:Read_String_From_File
IF
0AAB:   file_exists "CLEO/admin.txt"
then
    if
    0A9A: 30@ = openfile "CLEO/admin.txt" mode "rt"  // IF and SET
    then
        0AC8: 31@ = allocate_memory_size 20000
        repeat
        wait 1000
        10@++
        0AD7: read_string_from_file 30@ to 31@ size 20000
        chatmsg "%s" -1 31@
        until 0AD6:   end_of_file 30@ reached
        0AC9: free_allocated_memory 31@
        0A9B: closefile 30@
    end
end
0AB2: ret 0
 
Status
Not open for further replies.
Top