Batch, 117182 bytes
@set s= @set/ps= @set "t=%s:"=""%" @if "%t:"=""%"=="""=""""" goto g @for %%s in ("%s:"=%" "%s:"=""%""%t%")do @echo(%%~s>>_ @for %%s in (_)do @set s=%%~zs @del _ :g @cmd/cset/as/2-22*!!s
Doesn't workTesting for the empty string without breaking when quotes were present was cumbersome! Explanation:
@set s=
Clear s as set/p leaves s unchanged if the input was empty.
@set/ps=
Take input on STDIN into s.
@set "t=%s:"=""%"
Try to quote all of the quotes in s. However, because there's no safe wayif s is empty, Batch throws a wobbly, and sets t to detect it"="" instead, which still has an odd number of quotes. Works by printing
@if "%t:"=""%"=="""=""""" goto g
Quote all of the string twicequotes in t, onceand compare the result to ""="""". This can only happen if s was empty, in which case we skip the measurement step.
@for %%s in ("%s:"=%" "%t%")do @echo(%%~s>>_
Print s without quotes, once and s with quoted quotes doubled, then taking the resultingon separate lines to a temporary file. The ( is needed in case s only contains quotes.
@for %%s in (_)do @set s=%%~zs
Obtain the length, dividing by of the temporary file.
@del _
Delete the temporary file.
:g
Jump here if the input was empty.
@cmd/cset/as/2-2*!!s
Halve and subtract 2 from the length of the temporary file. However if the input was empty then s will be treated as the numeric value zero, and subtracting 2 for the CRLFresult of the expression is then zero as desired.
117 bytes without empty string support:
@set/ps= @for %%s in ("%s:"=%" "%s:"=""%")do @echo(%%~s>>_ @for %%s in (_)do @set s=%%~zs @del _ @cmd/cset/as/2-2
93 bytes if support for "s is not necessary, in which case the empty string can be supported (84 bytes without " or empty string support):
@set s= @set/ps= @set n=0 :l @if not "%s%"=="" set/an+=1&set "s=%s:~1%"&goto l @echo %n%