Page 1 of 1

Find the amount of characters in a string after SET /P

Posted: 07 Dec 2011 14:04
by alleypuppy
Hello,

Is it possible to find out how may characters a user has typed after reaching a SET /P prompt? If it is possible, which I'm assuming it is, I'm thinking I'd need to use a FOR loop, but I'm not sure how to set it up.

Any help would be appreciated. :wink:

Re: Find the amount of characters in a string after SET /P

Posted: 07 Dec 2011 14:19
by Ed Dyreen
'
This is the algorithm, it's gonna take time to figure it out, just ask, anything :wink:

Code: Select all

set "$vl=A%%~b"
set  "$l=0"
for %%! in (
   12, -1, 0
) do    set /a "$l|=1<<%%~!" &for %%? in (
   "!$l!"
) do    if /i ["!$vl:~%%~?,1!"] == [""] (
   set /a "$l&=~1<<%%~!"
)
set "%%~a=!$l!"
Thank dbenham, for a working example, see stringlen function :)
viewtopic.php?f=3&t=1827&start=0

Re: Find the amount of characters in a string after SET /P

Posted: 07 Dec 2011 16:06
by alleypuppy
Ed Dyreen wrote:'
This is the algorithm, it's gonna take time to figure it out, just ask, anything :wink:

Code: Select all

set "$vl=A%%~b"
set  "$l=0"
for %%! in (
   12, -1, 0
) do    set /a "$l|=1<<%%~!" &for %%? in (
   "!$l!"
) do    if /i ["!$vl:~%%~?,1!"] == [""] (
   set /a "$l&=~1<<%%~!"
)
set "%%~a=!$l!"
Thank dbenham, for a working example, see stringlen function :)
viewtopic.php?f=3&t=1827&start=0

Thanks! Now where would I place the variable defined in SET /P?

Re: Find the amount of characters in a string after SET /P

Posted: 07 Dec 2011 16:57
by Ed Dyreen
'
Use ben's function, now let's see
'
This should work :?

Code: Select all

@echo off

set "var=How long is this ?" &call :strLen var

pause
exit /b

:strLen string len -- returns the length of a string
  setlocal enabledelayedexpansion
  set "str=A!%~1!"
  set "len=0"
  for /l %%A in (12,-1,0) do (
    set /a "len|=1<<%%A"
    for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"
  )
  endlocal&if "%~2" neq "" (set /a %~2=%len%) else echo:%len%
exit /b

Code: Select all

18
Druk op een toets om door te gaan. . .

Re: Find the amount of characters in a string after SET /P

Posted: 07 Dec 2011 22:52
by alleypuppy
Ed Dyreen wrote:'
Use ben's function, now let's see
'
This should work :?

Code: Select all

@echo off

set "var=How long is this ?" &call :strLen var

pause
exit /b

:strLen string len -- returns the length of a string
  setlocal enabledelayedexpansion
  set "str=A!%~1!"
  set "len=0"
  for /l %%A in (12,-1,0) do (
    set /a "len|=1<<%%A"
    for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"
  )
  endlocal&if "%~2" neq "" (set /a %~2=%len%) else echo:%len%
exit /b

Code: Select all

18
Druk op een toets om door te gaan. . .
Works perfectly! Thank you!

Now, can you explain to me how it works? I cannot seem to wrap my mind around this loop lol

Re: Find the amount of characters in a string after SET /P

Posted: 07 Dec 2011 23:45
by Ed Dyreen
:lol:
It blew my mind as-well when I first saw it, I guess the most difficult part is the set /a "len|=1<<%%A" and the only possible way to understand it is using set /?

It uses the mathematical operators of the set command.
http://www.computerhope.com/sethlp.htm

Re: Find the amount of characters in a string after SET /P

Posted: 08 Dec 2011 11:21
by dbenham
Don't give me too much credit - I did not develop the algorithm. I just was the first to put the algorithm into a macro.

The macro is a direct descendent of the DosTips strlen function

The algorithm was developed by a bunch of very clever people (not me) in this Strlen boosted thread. There are additional optimizations suggested there that are not included in the macro or the standard DosTips function.


Dave Benham

Re: Find the amount of characters in a string after SET /P

Posted: 08 Dec 2011 18:05
by Ed Dyreen
'
Wauw, what a beautiful thread, that's worth a bookmark ! :P
viewtopic.php?f=3&t=1429&p=5385
Now I can truly understand binary math with the seti monster :D

I already found a case where I could use it to set a optional boolean value, instead of

Code: Select all

set "$sErr=%%~b" &set /a "$sErr|=0"
to

Code: Select all

set /a "$sErr=%%~b0>>3"
Thanks alot !

Re: Find the amount of characters in a string after SET /P

Posted: 08 Dec 2011 22:56
by orange_batch
Indeed, I use bitwise operations for anything involving powers of 2.

alleypuppy: viewtopic.php?f=3&t=1429&p=5537#p5537

I could also explain it as-is. It is based on adding bits together and seeing if the input string contains characters at the bits represented value. Counting down from 12 to 0 (13 iterations) can count a string up to about 8192 characters long. From 11 is 4096, from 10 is 2048 and so on, if for example you wanted to make the script milliseconds faster if you know an estimated max length of any strings you count.

1. Creates "binary" variable "len" with the value 4096.
2. Checks to see if the input string contains characters after position 4096.
3. If it doesn't, it removes the binary value 1 from the 12th position (value 4096) of the "binary" variable.
4. Repeats to check the next binary position (2048, continually lowering values).

What it accomplishes is, say you have a string 8035 characters long:

It counts 4096 + 2048 + 1024 + 512 + 256 + 64 + 32 + 2 + 1 to get 8035.

The process goes like... 4096 + 2048 + 1024 + 512 + 256 + 128 - 128 + 64 + 32 + 16 -16 + 8 - 8 + 4 - 4 + 2 + 1. Red numbers cause the value to go beyond the length of the string, so they are corrected.

The reason this works using only powers of 2 instead of say units of 10, 100, 1000 etc is because the nature of powers of 2 is you can divide them repeatedly all the way down to the number 1 as whole integers. Also, dividing the number by 2 is the quickest logical way. If you know the number game "higher or lower" where you have to guess say a number between 1 and 100, it's quickest to go like...

50 (halfway 1 and 100)
higher
75 (halfway 50 and 100)
higher
87 (*halfway 75 and 100)
lower
82 (*halfway 75 and 87)
higher
85 (*halfway 82 and 87)
lower
83 (*halfway 82 and 85)
bingo

*roughly, see this is why you can't do units of 10