Using the trick posted on ss64 by Jeb to save the backspace control character into a variable - I get strange results when 'overlapping' backspaces.
The example is in a code golfing challenge posted here: Backhanded^H^H^H^H^H^Hspaces (would appreciate any tips to get this code shorter).
Ungolfed it could look like this:
@echo off
setLocal enableDelayedExpansion
for /F %%a in ('"prompt $H&echo on&for %%b in (1) do rem"') do set DEL=%%a
set s=%1
echo %s:^H=!DEL!%
Basically, it uses Jeb's trick to save backspace as a variable, then uses string manipulation to replace all instances of ^H in the input string with that variable. Which works correctly for the following example, and similar inputs:
C:\>bsp.bat "testing^H^H^H test"
"test test"
However when 'overlapping' usage of ^H occurs, I get the following confusing (to me) output:
C:\>bsp.bat "AAA^HB^H^H"
"A"B
My question is - with the above example, why am I receiving this output instead of the expected "A"?
I don't understand why the "expected output" should be "A". See this character-by-character output:
bsp.bat "AAA^HB^H^H"
"
"A
"AA
"AAA
"AAA <- backspace, the cursor is over last "A"
"AAB
"AAB <- backspace, the cursor is over last "B"
"AAB <- backspace, the cursor is over second "A"
"A"B
The BS character just moves the cursor one character back. The "standard behaviour" of BackSpace key (also called "BackSpace echo") is "BackSpace+space+BackSpace".
By the way, this is the method I used to get BS character:
for /F %%a in ('echo prompt $H ^| cmd') do set BS=%%a
The "A"B result is to be expected because the backspace character (0x08) <BS> only moves the cursor back without erasing the character.
When you use PROMPT $H, it actually prints <BS><space><BS>. The first <BS> moves back one, the space overwrites (visually clears) the character, and then the 2nd <BS> moves back again to where you want to be.
The default delimiter with FOR /F is <tab><space>, so your assignment only preserves the first <BS>. Change the delimter to "r" and you get your desired result:
@echo off
setLocal enableDelayedExpansion
for /F "delims=r" %%a in ('"prompt $H&echo on&for %%b in (1) do rem"') do set DEL=%%a
set s=%1
echo %s:^H=!DEL!%
Or, preserve the single <bs> definition and explicitly overwrite the character yourself:
@echo off
setLocal enableDelayedExpansion
for /F %%a in ('"prompt $H&echo on&for %%b in (1) do rem"') do set DEL=%%a
set s=%1
echo %s:^H=!DEL! !DEL!%
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With