1

In input, I have a text file which contains numbers separated with a comma.

list.txt
111221,345,332133,66,5555, and so

I want to check the length of each string between the "," delimiter, in order to successively display the length of each word.

For example:

111221 is 6 characters long
345 is 3 characters long
332133 is 6 characters long
66 is 2 characters long
...

For this, I've written this code but it displays only the first word and the length is always "0". Without the for loop, it works fine for a single chain. Has anyone an idea to fix this? Thank you.

@echo off                   
setlocal enabledelayedexpansion enableextensions

for /f "delims=," %%a in ('type list.txt') do (
set string=%%a
set temp_str=%string%
set str_len=0

:loop
if defined temp_str (

set temp_str=%temp_str:~1%
set /a str_len+=1
goto:loop )

echo !string! is !str_len! characters long
)

pause
endlocal
Elhendriks
  • 119
  • 3
  • 14

2 Answers2

2
@echo off                   
setlocal enabledelayedexpansion enableextensions

for /f "delims=" %%f in ('type q35202446.txt') do (
 for %%a in (%%f) do (
  set "string=%%a"
  set "temp_str=!string!"
  set str_len=0
  CALL :loop
  echo !string! is !str_len! characters long
 )
)

GOTO :eof

:loop
if defined temp_str (
 set temp_str=%temp_str:~1%
 set /a str_len+=1
 GOTO loop )

GOTO :eof

I used a file named q35202446.txt containing your data for my testing.

Your problems are :

for /f ... reads a line at a time, so delims=, would provide you with just the first token in the line. Next iteration would read the next line (if it existed)

Putting the entire line ("delims=") into %%f allows you to use the default function of , (along with space, semicolon and tab) - a separator. The for ... %%a... sees a simple list of elements separated by commas.

You must use !string! to access the run-time value of string (with delayedexpansion invoked.) %string% will deliver the parse-time value of string which will be empty, hence reporting length 0.

Note the use of quotes in the string-assignment. That syntax ensures trailing spaces are not included in the string assigned.

A label terminates a "block" (parenthesised series of statements) so I've moved the length-calculator to a subroutine.

Your echo was correctly using !var! to access the run-time value of the variables.

Magoo
  • 77,302
  • 8
  • 62
  • 84
2

You should use for /f to read line-by-line, then an inner for to tokenize each line on the commas. Something like this:

@echo off                   
setlocal

for /f "usebackq delims=" %%a in ("list.txt") do (
    for %%t in (%%a) do (
        call :length len %%t
        setlocal enabledelayedexpansion
        echo %%t is !len! characters long.
        endlocal
    )
)

goto :EOF

:length <return_var> <string>
setlocal enabledelayedexpansion
if "%~2"=="" (set ret=0) else set ret=1
set "tmpstr=%~2"
for %%I in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
    if not "!tmpstr:~%%I,1!"=="" (
        set /a ret += %%I
        set "tmpstr=!tmpstr:~%%I!"
    )
)
endlocal & set "%~1=%ret%"
goto :EOF

Credit: the :length function is based on jeb's answer here. It's much more efficient than a goto loop.

Community
  • 1
  • 1
rojo
  • 24,000
  • 5
  • 55
  • 101