0

I have found and tried many examples to count the number of tokens in a for /f loop but I only get a count of 1.

This is what I have tried (my best attempt after a lot of hacking):

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "inputVar=13:45:33"
echo inputVar = %inputVar%
set tokenCount=0

for /F "tokens=* delims=:" %%I in ("%inputVar%") do (
    set /a tokenCount=%tokenCount% + 1
    set II=%%I
    set JJ=%%J
    set KK=%%K
)
echo tokenCount = %tokenCount%
echo II = %II%
echo JJ = %JJ%
echo KK = %KK%
pause

exit

So, what's wrong? Or, what will work?

I changed tokens=1-3 to tokens=* and I expected the tokenCount to equal 3.

This is just a portion of my total script to simplify the question of how I can determine how many tokens were processed.

  • 2
    The code you've posted does not define a problem. You have clearly preset the number of tokens as a maximum of 3 with `tokens=1-3`. Instead of trying to submit code which is irrelevant to a real world task, how about you [edit] your question to include your actual problem, so that we can assist you with that instead. – Compo Jul 07 '22 at 14:24
  • 2
    BTW, you don't need to enable delayed expansion for the code you have included, although it does mean you could have used ```set /a tokenCount=!tokenCount! + 1```. Just remove it, and use ```set /a tokenCount += 1``` instead. – Compo Jul 07 '22 at 14:30
  • `for /F "tokens=1-3 delims=:" %%I in ("%inputVar%") do (` means split up the string `13:45:33` into substrings (tokens) using (a series of) `:` as string delimiters and if the first substring does not start with a semicolon, assign the first substring `13` to the specified loop variable `I`, the second substring `45` to the next loop variable `J` according to ASCII table and the third substring `33` to the next but one loop variable `K` and ignore all further substrings (none in this case) and then run __once__ the commands in the command block which can use the up to three strings. – Mofi Jul 07 '22 at 15:13
  • You can use in the command block in addition to the last three set command lines `if not "%%~K" == "" (set "tokenCount=3") else if not "%%~J" == "" (set "tokenCount=2") else set "tokenCount=1"` to get the number of substrings (tokens) really get from the processed string. But if you just want the number of `:` delimited strings on a line, run `for %%I in (%inputVar::=,%) do set /A tokenCount+=1` Special hint: Never use just `exit` at end of the batch file. It is completely unnecessary and just counterproductive on [debugging the batch file](https://stackoverflow.com/a/42448601/3074564). – Mofi Jul 07 '22 at 15:15
  • For completeness `for /F "tokens=* delims=:" %%I in ("%inputVar%") do (` means remove all colons from the beginning of the string and if the remaining string does not start with the default end of line character `;`, assign the string to the loop variable `I` without splitting it up on each `:` at all. `*` after a token number (`0` on no token number specified at all) means do not split up the string further after token `X`. You can see that on using for example `tokens=1*` which assigns `13` to loop variable `I` and `45:33` to loop variable `J` and there is no more loop variable. – Mofi Jul 07 '22 at 15:15
  • There must be at least one string assigned to the specified loop variable to run the commands in the command block at all. `for /F "tokens=2 delims=:" %%I in ("::13::") do echo Second token is: "%%I"` outputs nothing as there is no second substring. `for /F "tokens=2 delims=:" %%I in ("::13::23:::") do echo Second token is: "%%I"` outputs `Second token is: "23"` and `for /F "tokens=2 delims=:" %%I in ("::;13::23:::") do echo Second token is: "%%I"` outputs also nothing because of first substring although not referenced for loop variable assignment begins after two removed `:` with a semicolon. – Mofi Jul 07 '22 at 15:23
  • Thanks Mofi. After reading your comments I was gradually comin to realize that the Do block is executed only once. That makes a big difference on my perception of how it works. The post here: https://stackoverflow.com/questions/5473840/last-token-in-batch-variable also helps me understand this a little better. I need to do some more hacking. Thanks Again. – SloppyCoder Jul 07 '22 at 15:28

1 Answers1

0

Personally, I'd use

set /a tokencount=0
call :counttokens %inputvar::= %
echo tokencount=%tokencount%

...

:counttokens
if "%1"=="" (goto :eof) else shift&set /a tokencount+=1&goto counttokens

which should count your tokens.

I'm assuming you're familiar with the requirements for internal subroutine.

No info about what you then want to do with which tokens, so I'll say no more.

Magoo
  • 77,302
  • 8
  • 62
  • 84