Control characters and string manipulation
Using a trick posted on ss64 by Jeb to store the backspace control character in a variable - I get weird results when there are "overlapping" backspaces.
An example is given in the following golfing example: Backhanded ^ H ^ H ^ H ^ H ^ H ^ Hspaces (would appreciate any advice on making this code shorter).
Ungolfed it might 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 store backspace as a variable and then uses string manipulation to replace all instances ^H
in the input string of that variable. Which works correctly for the following example and similar inputs:
C:\>bsp.bat "testing^H^H^H test"
"test test"
However, when the usage "overlap" occurs ^H
, I get the following confusing (for me) output:
C:\>bsp.bat "AAA^HB^H^H"
"A"B
My question is - with the above example, why am I getting this output instead of what I expected "A"
?
source to share
I don't understand why the "expected result" should be "A". See this output by symbol:
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 simply moves the cursor back one character. The "standard behavior" of the BackSpace key (also called "BackSpace echo") is "BackSpace + space + BackSpace".
By the way, this is the method I used to get the BS character:
for /F %%a in ('echo prompt $H ^| cmd') do set BS=%%a
source to share
The result is to "A"B
be expected because the backspace character (0x08) <BS>
moves the cursor back without erasing the character.
When you use PROMPT $ H, it actually prints <BS><space><BS>
. The first <BS>
moves backwards, the space overwrites (visually clears) the character, and then the second <BS>
moves back to where you want to be.
The default delimiter with FOR / F is equal <tab><space>
, so your assignment only keeps the first one <BS>
. Change the delimiter to "r" and get the 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 keep a single definition <BS>
and rewrite the character explicitly:
@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!%
source to share