1

I have three strings t1=3, t2=1 and t3=5.

want to reverse these strings so that t1=5, t2=1 and t3=3.

Together they form a number (input:315 and output:513).

I need to reverse the number they form.

I tried to do this:

set "rest2=%t1%"
set "t1=%t3%"
set "t3=%rest2%"

when I tried it, it removed t1 from the number they formed (input:315 and output: 13).

I dont know why that happend.

Jonny C
  • 1,943
  • 3
  • 20
  • 36

2 Answers2

2

Excuse me. There is no way that your code produce 13 as output. If the code is inside parentheses, then the variable rest2 is undefined, so the variable removed is t3 and hence the output must be 51. You may test this point in the following code:

@echo off
setlocal

set t1=3
set t2=1
set t3=5

echo %t1%%t2%%t3%

(
set "rest2=%t1%"
set "t1=%t3%"
set "t3=%rest2%"
)

echo %t1%%t2%%t3%

I suggest you to carefully review your code looking for errors in other parts.

If the problem is that the code is in parentheses, the way to fix it is via Delayed Expansion as rojo explained in his answer. However, if the code is not in parentheses, then you should know that you may achieve the exchange of t1 and t3 whitout using the rest2 auxiliary variable as long as you place both assignments in the same line:

set "t1=%t3%" & set "t3=%t1%"

This works because variables enclosed in percents are replaced by their values before the resulting line is executed.

Aacini
  • 65,180
  • 12
  • 72
  • 108
0

I'm guessing your set commands all live within a parenthetical code block (such as a for loop), and you aren't employing delayed expansion when you should be. If that's the case, you can probably fix your existing code this way:

setlocal enabledelayedexpansion
set "rest2=!t1!"
set "t1=!t3!"
set "t3=!rest2!"

Just so I feel like I've done something, here's a utility function that'll reverse a string that might solve your issue. This one has a limit of 100 characters for the sake of small execution time. I'm guessing this will be fine for most situations.

@echo off
setlocal

set /P "input=Input? "
call :reverse flipped "%input%"

echo %input% reversed is %flipped%
rem // end main runtime
goto :EOF

rem // functions

:reverse <return_var> <string>
setlocal enabledelayedexpansion
set "ret=" & set "str=%~2"
for /L %%I in (0,1,100) do (
    if "!str!"=="" for %%a in ("!ret!") do (
        endlocal & set "%~1=%%~a" & exit /b
    )
    set "ret=!str:~0,1!!ret!"
    set "str=!str:~1!"
)

If you'd rather have the function work up to the limit of characters a variable can carry, you can increase the 100 to 8192, but that'll cause the for /L loop to loop 8192 times regardless of whether broken by exit /b1. There's not really a graceful way to break out of for /L (although it is much faster than a goto loop).

Adding a function to get the length of the string before firing the for /L loop can make your code more efficient for long strings while not significantly impacting short ones. Although this is a lot more code, it is faster than the script above.

@echo off
setlocal

set /P "input=Input? "
call :reverse flipped "%input%"

echo %input% reversed is %flipped%
goto :EOF

:reverse <return_var> <string>
setlocal enabledelayedexpansion
set "ret=" & set "str=%~2" & call :length len "%~2"
for /L %%I in (0,1,%len%) do (
    if "!str!"=="" for %%a in ("!ret!") do (
        endlocal & set "%~1=%%~a" & exit /b
    )
    set "ret=!str:~0,1!!ret!"
    set "str=!str:~1!"
)

: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%"
exit /b 0

1 When goto :EOF or exit /b is encountered within a for /L loop, the counting continues, although the stuff after do is ignored.

rojo
  • 24,000
  • 5
  • 55
  • 101