Google 网上论坛不再支持新的 Usenet 帖子或订阅项。历史内容仍可供查看。

Get String Length

已查看 82 次
跳至第一个未读帖子

Tom Del Rosso

未读,
2021年9月1日 15:30:212021/9/1
收件人
Here's a subroutine to get the length of a string that uses successive
approximation so it runs very fast because it only loops 13 times (once
for each bit of the resulting number) no matter how long the string is.


:GetStringLength
rem Takes string variable NAME which must have no spaces. Returns
variable: StringLength
rem Environment variables go up to 8191 characters so approximation
starts with 4096 which is the MSB.
rem Practical limit is 8185 because "set x=" has 6 characters
if [%1]==[] set "StringLength=" & goto :eof
if not defined %1 set /a StringLength=0 & goto :eof
set /a GetStringLength_PlaceValue=4096
set /a GetStringLength_Guess=0
:GetStringLength_Loop
set /a GetStringLength_Guess^|=GetStringLength_PlaceValue
set /a GetStringLength_Skip=GetStringLength_Guess-1
call set "GetStringLength_Char=%%%1:~%GetStringLength_Skip%,1%%"
if not defined GetStringLength_Char set /a
GetStringLength_Guess^^=GetStringLength_PlaceValue
set /a GetStringLength_PlaceValue/=2
if %GetStringLength_PlaceValue% GTR 0 goto :GetStringLength_Loop
set /a StringLength=GetStringLength_Guess
set "GetStringLength_String="
set "GetStringLength_PlaceValue="
set "GetStringLength_Guess="
set "GetStringLength_Skip="
set "GetStringLength_Char="
goto :eof



Tom Del Rosso

未读,
2021年9月1日 15:39:222021/9/1
收件人
Oops the REM lines wrapped and one other line did:

JJ

未读,
2021年9月2日 00:13:232021/9/2
收件人
On Wed, 1 Sep 2021 15:30:18 -0400, Tom Del Rosso wrote:
> Here's a subroutine to get the length of a string that uses successive
> approximation so it runs very fast because it only loops 13 times (once
> for each bit of the resulting number) no matter how long the string is.
[snip]

Nice. Would definitely be part of by batch subs library.

The method could be used as a fast `HasStr` sub. :)

Tom Del Rosso

未读,
2021年9月2日 02:55:352021/9/2
收件人
I just noticed that there is a vestigial line still in there.

Remove this:

set "GetStringLength_String="



Tom Del Rosso

未读,
2021年9月2日 03:08:042021/9/2
收件人
What does HasStr do? Find a substring?


--
Defund the Thought Police


Harry Potter

未读,
2021年9月2日 15:49:212021/9/2
收件人
JJ, I have a batch file that backs up a user program without rebuildable files to a specified folder using 7Zip and one that returns the current date. The former is hard-coded for my needs but can be customized by other downloaders, and the latter simply returns the current date in the environment variable %DATE2%. The former first asks for the subfolder (I call it the system, as that is how I organize my backups, but you can change the prompt text.) then makes a temporary copy of the program, deletes rebuildable files (mainly programs and object files), compresses the folder, attaches the date to the name, moves the file to the destination and then deletes the temporary folder. Are you interested? If so, I ask for a way to send you the files in any way you like. I have some information on sourceforge.net and can upload them there, or I can e-mail you the files.

BTW, I have other batch files that I use. I'll look at them now.

Harry Potter

未读,
2021年9月2日 16:11:412021/9/2
收件人
On Thursday, September 2, 2021 at 3:49:21 PM UTC-4, Harry Potter wrote:
> JJ, I have a batch file that backs up a user program without rebuildable files to a specified folder using 7Zip and one that returns the current date. The former is hard-coded for my needs but can be customized by other downloaders, and the latter simply returns the current date in the environment variable %DATE2%. The former first asks for the subfolder (I call it the system, as that is how I organize my backups, but you can change the prompt text.) then makes a temporary copy of the program, deletes rebuildable files (mainly programs and object files), compresses the folder, attaches the date to the name, moves the file to the destination and then deletes the temporary folder. Are you interested? If so, I ask for a way to send you the files in any way you like. I have some information on sourceforge.net and can upload them there, or I can e-mail you the files.
>
> BTW, I have other batch files that I use. I'll look at them now.

I looked at the batch files. They are mostly for my work with emulation, but I have some batch files to compress folders using 7Zip or WInMount to specific locations and assemble a code file to a .COM file using NASM. Is anybody interested?

Harry Potter

未读,
2021年9月2日 16:18:512021/9/2
收件人
I also have two batch files to compress executables using UPX, one to compress files to .gz files using 7Zip and one that automatically decompresses archives to a specific folder.

Harry Potter

未读,
2021年9月2日 16:31:522021/9/2
收件人
The easiest way to use them is to add them to the SendTo folder using SendTo Toys. You can find it on freewarefiles.com.

JJ

未读,
2021年9月3日 01:11:262021/9/3
收件人
Yes. A sub to check the existence of a substring when the index of the
substring doesn't matter. It's basically just a sub which finds the index of
a substring.

Tom Del Rosso

未读,
2021年9月3日 03:07:212021/9/3
收件人
So you're thinking of doing it this way?


@echo off
set string=Where is the substring?
set substring=the

call set poststring=%%string:*%substring%=%%

call :GetStringLength string
set /a string_len = StringLength
call :GetStringLength substring
set /a substring_len = StringLength
call :GetStringLength poststring
set /a poststring_len = StringLength

set /a position = string_len - substring_len - poststring_len

echo %string%
echo %substring%
if %poststring_len% LSS %string_len% echo Has string after position
%position%.

pause
goto :eof

Robert Prins

未读,
2021年9月3日 05:47:052021/9/3
收件人
We're living in 2021, why write convoluted code when there are much better
languages to do this? REXX (available for about every OS) can do it in one line,
and if you only use Windoze, PowerShell would probably do it.

Robert
--
Robert AH Prins
robert(a)prino(d)org
The hitchhiking grandfather - https://prino.neocities.org/indez.html
Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html

Kenny McCormack

未读,
2021年9月3日 16:20:492021/9/3
收件人
In article <sgsqun$h78$1...@dont-email.me>,
Robert Prins <rob...@prino.org> wrote:
...
>We're living in 2021, why write convoluted code when there are much better
>languages to do this? REXX (available for about every OS) can do it in one line,
>and if you only use Windoze, PowerShell would probably do it.

Because those are the rules of this newsgroup. Like several other Usenet
newsgroups, this group is kind of an abstraction. I.e., the issue isn't
solving specific problems by whatever means work - i.e., if it works, it is
good mentality. Rather, it is solving the problem using only a specific
set of tools - sort of like "straight edge and compass" problems in
geometry.

The rules - which, BTW, I didn't make up, and I, of course, have no
authority to enforce, but which I have gleaned from years of observing this
group - is that you can only solve problems using functionality found in
CMD.EXE itself (and COMMAND.COM before then). You are not allowed to use
any external tools or languages. To do so would be cheating.

Note, BTW, that you are sort of allowed (wink, wink, nudge, nudge) to cheat
semi-legally by using things like WishScript, or JavaScript, or
WhateverScript or PowerShell, because you can sort of make a case that
these things are now builtin on most modern Windows installs. But the
point is that most people still using DOS/Windows (without any external
tools) are probably doing so on older machines (I still have several XP
machines), and those tools won't be present on those older machines.

In fact, many of the people still using CMD.EXE batch language, are
probably running their PCs by oil light, in a cave somewhere in Afghanistan
(or similar).

BTW, REXX? Seriously???

--
"Only a genius could lose a billion dollars running a casino."
"You know what they say: the house always loses."
"When life gives you lemons, don't pay taxes."
"Grab 'em by the p***y!"

Zaidy036

未读,
2021年9月3日 17:23:152021/9/3
收件人
another batch:

:: _StrngLen.bat

:: _StrngLen.bat "string" Length at exit
:: _StrngLen.bat "string" _Len Variable for length
:: https://ss64.com/nt/syntax-strlen.html

@ECHO OFF
ECHO(
FOR %%F IN (%1 %2 %3 %4 %5 %6 %7 %8 %9) DO CALL :LnCalc %%F

:EOF

:LnCalc
Setlocal EnableDelayedExpansion
:: strLen String [RtnVar]
:: -- String The string to be measured, surround in quotes
if it contains spaces.
:: -- RtnVar An optional variable to be used to return the
string length.
ECHO(
SET "s=#%~1"
SET "len=0"
For %%N in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%N,1!" neq "" (
SET /a "len+=%%N"
SET "s=!s:~%%N!"
)
)
:: Endlocal & IF "%~2" neq "" (SET %~2=%len%) else ECHO %len% of %1
Endlocal & ECHO %len% of %1
GOTO :EOF

Zaidy036

未读,
2021年9月3日 18:00:132021/9/3
收件人

Tom Del Rosso

未读,
2021年9月3日 22:26:122021/9/3
收件人
Robert Prins wrote:
>
> We're living in 2021, why write convoluted code when there are much
> better languages to do this? REXX (available for about every OS) can
> do it in one line, and if you only use Windoze, PowerShell would
> probably do it.

You can also do it with one line in a batch file like so:

call :GetStringLength

Everyone here knows other languages. We use batch when it's the best
choice.

If it's never the best choice for you, then you wouldn't have come here.

BTW REXX was included in OS/2 in 1993. I was an advocate. No one
listened. Since you emphasize that it's 2021 you probably should have
suggested Python.

And also, successive approximation isn't convoluted. It has a lot of
applications. There are successive approximation register chips that do
it in hardware for A/D conversion. My method was IMO very
straightforward and readable, and I'm a fan of Knuth's law, "A program
should be readable by humans first and computers second."



Tom Del Rosso

未读,
2021年9月4日 02:49:422021/9/4
收件人
Another way to do successive approximation. And it's probably faster.
Did you just write that?

JJ

未读,
2021年9月4日 05:46:552021/9/4
收件人
On Fri, 3 Sep 2021 03:07:18 -0400, Tom Del Rosso wrote:
> JJ wrote:
>> On Thu, 2 Sep 2021 03:08:01 -0400, Tom Del Rosso wrote:
>>>
>>> What does HasStr do? Find a substring?
>>
>> Yes. A sub to check the existence of a substring when the index of the
>> substring doesn't matter. It's basically just a sub which finds the
>> index of a substring.
>
> So you're thinking of doing it this way?
[snip]

Huh? Why are you using string lengths to check the existence of a substring?

Zaidy036

未读,
2021年9月4日 11:56:222021/9/4
收件人

Tom Del Rosso

未读,
2021年9月5日 12:53:222021/9/5
收件人

JJ

未读,
2021年9月6日 03:08:002021/9/6
收件人
By "method", I meant the algorithm. Not the sub itself as is.

But nevermind though, cause I found out that the divide-and-conquer
algorithm can't be used as a faster substring search than sequential one.

Tom Del Rosso

未读,
2021年9月6日 12:45:492021/9/6
收件人
If the objective is to find exactly where the substring exists then it
could actually be faster for a long string.

I mean using the asterisk in string substitution like below, and testing
the length of the result. Even more so if you already know the length of
the original string.

call set poststring=%%string:*%substring%=%%



JJ

未读,
2021年9月7日 07:24:452021/9/7
收件人
Oh, I see. I didn't realize asterisk as a leading wildcard is supported for
string replacement. That's indeed a faster way to find the substring offset.
Thanks.

Though, in a different topic but related to that asterisk wildcard...
Although I haven't yet need to do it, is it possible to replace literal
asterisk character itself excluding any characters preceeding it, using
replace string substitution? I've tried escaping the asterisk and using
double asterisks, but it doesn't work. For example, to replace `*` with `;`,
so that e.g. `abc*def` would become `abc;def`.

@echo off
setlocal
call :repesc "abc*def" result
echo escape=%result%
call :repdbl "abc*def" result
echo double=%result%
goto :eof

:repesc
set "a=%~1"
set "%2=%a:^*=;%"
goto :eof

:repdbl
set "a=%~1"
set "%2=%a:**=;%"
goto :eof

Here, the result are:

escape=abc*def
double=;def

mokomoji

未读,
2021年9月7日 12:34:342021/9/7
收件人
2021년 9월 4일 토요일 오전 6시 23분 15초 UTC+9에 Zaidy036님이 작성한 내용:
@echo off
setlocal
Set "_demo=some example string don with enabledelayedexpansion version"
Call :strlen "_length" "%_demo%"
Echo String is %_length% characters long
goto :end

:strlen
set "s=#%~2"
set "len=0"
for %%N in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
for /f "delims=" %%f in ('echo "%%s:~%%N,1%%"') do (
if "%%~f" neq "" (
call set /a "len+=%%N"
call set "s=%%s:~%%N%%"
rem call echo %%f %%N %%s%%
)))
if "%~1" neq "" (set %~1=%len%) else (echo %~1 = %%%~1%%)
goto :eof

:end
endlocal
pause


god them..~!!

Tom Del Rosso

未读,
2021年9月7日 17:10:402021/9/7
收件人
I guess you could use ** to chop off the first part of the string, then
measure its length and then reassemble it, like

set x=abc*def
set y=%x:**=;%
[...get length of x and y and x-y...]
set /a prefix_len = x_len - y_len
call set z=%%x:~0,%prefix_len%%%%y%
set z
pause


But my first idea started in the wrong direction.
I thought of putting something before the asterisk like

set y=%x:c*=c;%

which would work if you know the letter before it is c.

To try every letter you have to use FIND to do the substitution at the
right time (or else it would change back when it got to the next
letter), like this, but it's much slower.

@echo off
set y=abc*def
set "z="
for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (
echo %y% | find "%%a*" >nul
if not errorlevel 1 (
call set z=%%y:%%a*=%%a$%%
)
)
set y
set z
pause
0 个新帖子