Page 2 of 3

Posted: Mon Oct 13, 2003 4:58 pm
by Fred
ebs: yes, I will probably add this.

karbon: Nb = CountString(String$, StringToCount$). You could of course provide a single char string if needed :)

Posted: Mon Oct 13, 2003 5:01 pm
by Karbon
Eeeeeeeeeexcellent!

Posted: Mon Oct 13, 2003 5:31 pm
by ebs
Fred wrote:May be a CountString() command is needed ? :)
Fred,
It might be handy, but my 2-step procedure doesn't take much more effort.
Eric

Posted: Mon Oct 13, 2003 7:09 pm
by FloHimself
hi,
until fred implemented this natively to purebasic,
you can use the "Tally" function from this userlib.
its doing the same as the mentioned
CountString(String$, StringToCount$)
see example..

http://www.florian-s.com/download/PureBasic/PBTally.zip

Posted: Mon Oct 13, 2003 8:29 pm
by Froggerprogger
Errr... What about a string like

Code: Select all

"word1                   word2"
There are two words inside it, but your Procedures returns 19 :wink:

Posted: Mon Oct 13, 2003 8:32 pm
by Karbon
To work properly any word count function would have to look at whitespace in context..

PHP's str_word_count() says :
For the purpose of this function, 'word' is defined as a locale dependent string containing alphabetic characters, which also may contain, but not start with "'" and "-" characters.
Which sounds about right to me..

Posted: Mon Oct 13, 2003 8:42 pm
by FloHimself
thats correct. if you set StringToCount$ = " ", it counts all spaces.
in your example 19

this function will not count "words" of a string! it counts how often the string/char occurs in a string.

btw:
i have wrapped some fuctions from a regular expressions library to a purebasic user library. it works well and maybe its more useful to count real "words". at the moment i wait for a statement from the author, if i am allowed to use / release here such a wrapper.

[edit]
in the moment i was typing this post, i recieved the awaited mail.
Yes, go ahead, no problems.
so wait until i've done some documentation, then i will release the regexp lib...

Posted: Mon Oct 13, 2003 9:33 pm
by FloHimself
here is a "CountWords" user lib.. a fast hack!
see example..

http://www.florian-s.com/download/PureB ... tWords.zip

Posted: Tue Oct 14, 2003 6:49 pm
by FloHimself
and here the mentioned regexp purebasic user lib.
:arrow: http://www.florian-s.com/download/PureB ... RegExp.zip

Posted: Tue Oct 14, 2003 7:45 pm
by Psychophanta
Summers, i made this useful procedure in ASM some months ago (i didn't make a PBlib with it because i thought it would be included soon in standard PB):

Code: Select all

Procedure.l CountStrings(a.s,s.s) 
  !cld          ;clear DF (Direction Flag) 
  !mov edi,dword[esp]   ;load edi register with pointer to first string 
  !mov esi,dword[esp+4] ;load esi register with pointer to second string (the string to search) 
  !xor eax,eax    ;set eax register to NULL 
  !mov bl,al      ;set bl register to NULL 
  !mov edx,esi  ;save this value in edx to avoid, as much as possible, to have to read data from memory in the main loop. 
  !;If any of two strings is empty then end program and matches found is 0; 
  !cmp byte[edi],bl  ;test if first string is empty 
  !jz fin           ;if so, then end 
  !cmp byte[esi],bl  ;test if second string is empty 
  !jz fin           ;if so, then end 
  !;Mainloop: 
  !mainloop: 
  !cmpsb  ;what this instruction do is just compare byte[edi] with byte[esi] and increment edi and esi values by 1 
  !jz match ;if byte[edi]=byte[esi] then goto match label, because a match byte was found... 
  !mov esi,edx  ;restore this 
  !cmp byte[edi],bl  ;check if end of first string is reached 
  !jnz mainloop   ;if not reached then compare next bytes 
  !fin: 
  ProcedureReturn 
  !match: ;here we have got inside a second treatment: We are in a possible total match, lets see if it is a complete match or it is a fake: 
  !cmp byte[esi],bl  ;check if end of second string is reached 
  !jz @f   ;if so, here was a complete match 
  !cmpsb   ;compare one more byte 
  !jz match   ;if equal, lets see if the deceit continues, or rather it could be a real complete match. 
  !dec edi  ;ohhh! it was a deceit! It wasn't a complete match. So return back the first string counter by 1. 
  !mov esi,edx  ;and restore this 
  !jmp mainloop ;What a patient! lets continue searching for another possible match and why not, a possible complete match... 
  !;complete match was found: 
  !@@:inc eax    ;increment complete matches counter 
  !mov esi,edx  ;restore this 
  !jmp mainloop   ;lets search for another possible complete match! 
EndProcedure 

;Grrr!: Z-80 had conditional CALL, Ix86 doesn't !? 
a$="ureruPururePe ruPurePurPuPure uresdfhg ureeurPeruPuruee sPuuredil hPur eurePuree upurerePuret" 

MessageRequester("",Str(CountStrings(a$,"Pure")),0) 

;Can use function input parameters as normal pointers: 
;Procedure.l CountStrings(*a,*s) 
;but then you have to call function using pointers too: 
;CountStrings(@a$,@"Pure")
and you can find this and another good things at the Code-Archive in www.purearea.net, in String-Handling section, thanx to Andre Beer.

Posted: Sun Jul 24, 2005 12:26 am
by Kale
This one seemed to work for me, where there was no duplicated whitespace:

Code: Select all

Procedure CountWords(String.s)
	Repeat
		CurrentByte = @String + i
		If PeekB(CurrentByte) = 32
			Count + 1
			i + 1
			Continue
		EndIf
		i + 1
	Until PeekB(CurrentByte) = 0
	ProcedureReturn Count + 1
EndProcedure
:)

Posted: Sun Jul 24, 2005 7:34 am
by Psychophanta
Kale, Since some versions ago Fred created:
CountString(String$, StringToCount$)
And it really works fine and is fast
Perhaps you can make use of this function to make a task to find the word number in an ascii text. :wink:

Posted: Sun Jul 24, 2005 8:07 am
by PB
> No offence, but this has the worst search page ever

See here then: viewtopic.php?t=14552

Posted: Mon Jul 25, 2005 12:14 am
by Kale
Kale, Since some versions ago Fred created:
CountString(String$, StringToCount$)
And it really works fine and is fast
Really?

*digs out manual*

Oh Yeah!!! Ta m8! :)

Might need to give the manual another read sometime.

Word Count

Posted: Mon Jul 25, 2005 4:43 pm
by PB&J Lover
Here are two simple procedures that work together to do it.

Code: Select all

Procedure.s RemoveExtraSpaces(Text$)
  While FindString(Text$,"  ",1) : Text$ = ReplaceString(Text$,"  "," ", 1) : Wend
ProcedureReturn Text$
EndProcedure

Procedure.l WordCount(Text$)
count.l = 1 : Text$ = RemoveExtraSpaces(Text$)
 While StringField(Text$, count, " ") : count + 1 : Wend
ProcedureReturn count - 1
EndProcedure