Return value by reference from within a for loop

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
dthvw
Posts: 2
Joined: 05 Oct 2014 02:01

Return value by reference from within a for loop

#1 Post by dthvw » 05 Oct 2014 02:21

Hi,

I would like to use call by reference. This works fine:
a.bat

Code: Select all

 call b.bat c
 echo %c%
b.bat

Code: Select all

 set %1=555

However inside a FOR loop:
%1=%aa <--- this works fine
%1='d' <--- this does not work, although d contains some valid value

if using some call (from inside the loop) the original %1 value is destroyed and does not accept a new value

How do I return a !value! by reference from within a FOR loop?

Thanks

Henk

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Return value by reference from within a for loop

#2 Post by foxidrive » 05 Oct 2014 04:02

delayed expansion is most often needed to display changed variables in a loop.

Give an example of how you are using this if you need some actual code.

dthvw
Posts: 2
Joined: 05 Oct 2014 02:01

Re: Return value by reference from within a for loop

#3 Post by dthvw » 06 Oct 2014 11:00

Hi,

file a.bat:

Code: Select all

  rem # don't show console output
  @echo off
  rem # call some batch file with argument c
  call b c
  rem # show contents of c
  echo %c%
  rem # wait for user input
  pause
file b.bat:

Code: Select all

  rem # enable evaluating loop variables at runtime
  SetLocal EnableDelayedExpansion
  rem # handle all individual lines in file 'd.txt'
  for /f %%a in (d.txt) do (
    rem # count line numbers searched
    set /a line=!line!+1
    rem # the requested keyword 'house' is found
    if %%a==house (
      rem # report found line number :
      set %1=!line!                     <--- this does not work
      rem # exit batch
      exit /b
    rem # if
    )
  rem # for
  )
file d.txt:

Code: Select all

car
house
boat

It's not the line number that's important it's just the way how a !value! can be returned. I would like it to return it's content value '2' int %1. Remember, calls inside the loop are not allowed as they destroy the %1 reference.
Hope this makes it clear.

Squashman
Expert
Posts: 4471
Joined: 23 Dec 2011 13:59

Re: Return value by reference from within a for loop

#4 Post by Squashman » 06 Oct 2014 14:05

b.bat

Code: Select all

@echo off
SetLocal EnableDelayedExpansion
rem # handle all individual lines in file 'd.txt'
for /f %%a in (d.txt) do (
   rem # count line numbers searched
   set /a line=!line!+1
   rem # the requested keyword 'house' is found
   if %%a==house (
      GOTO END
   )

 )
:END
endlocal &set %1=%line%

Squashman
Expert
Posts: 4471
Joined: 23 Dec 2011 13:59

Re: Return value by reference from within a for loop

#5 Post by Squashman » 06 Oct 2014 14:18

Or this per Dbenham,
b.bat

Code: Select all

@echo off
SetLocal EnableDelayedExpansion
rem # handle all individual lines in file 'd.txt'
for /f %%a in (d.txt) do (
   rem # count line numbers searched
   set /a line=!line!+1
   rem # the requested keyword 'house' is found
   if %%a==house (
      for /f "delims=" %%B in ("!line!") do endlocal & set "%1=%%B"
      exit /b
   )

 )

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Return value by reference from within a for loop

#6 Post by foxidrive » 06 Oct 2014 16:50

@dthvw - You are using setlocal in b.bat and this executes an implied endlocal when b.bat terminates, nuking your variable.

A solution is to enable delayed expansion in a.bat and remove the same line from b.bat

Code: Select all

  rem # don't show console output
  @echo off
  setlocal enabledelayedexpansion
  rem # call some batch file with argument c
  call b c
  rem # show contents of c
  echo %c%
  rem # wait for user input
  pause



Code: Select all

  rem # enable evaluating loop variables at runtime
  rem # handle all individual lines in file 'd.txt'
  for /f %%a in (d.txt) do (
    rem # count line numbers searched
    set /a line=!line!+1
    rem # the requested keyword 'house' is found
    if %%a==house (
      rem # report found line number :
      set %1=!line!
      rem # exit batch
      exit /b
    rem # if
    )
  rem # for
  )

Post Reply