1

i am hoping there will be a solution to this,

I am wondering if some kind person can help me to create a input line which features dots as the field of entry...(every time a letter is typed, a dot is replaced)

Here's an example:

Action [cursor]· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

here is what I have so far, but I am stuck.

@echo off
title Input with dots
set /p action = "·······················································"
if %action% == option1 goto print1
:print1
echo this works!
pause
exit
rojo
  • 24,000
  • 5
  • 55
  • 101

2 Answers2

2

You can output the dots, move the cursor backward by outputting a bunch of backspace characters, then prompt the user. To output a backspace character, you must capture a backspace to a variable.

@echo off & setlocal

rem // capture backspace character to a variable
rem // credit: http://www.dostips.com/forum/viewtopic.php?p=22010#p22010
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"

rem // cosmetic, non-functional prompt:
<NUL set /P "=Fill in the blank: .................................................."

rem // backspace 50 times (one for each dot)
for /L %%I in (1,1,50) do <NUL set /P "=%BS%"

rem // real prompt this time
set /P "response="

echo You entered "%response%".

pause
exit /b

Based on @TripeHound's excellent idea of using a carriage return to move the text cursor, here's an example of using a batch function to determine the number of dots to pad the line programmatically:

@echo off
setlocal

call :prompt "Fill in the blank:" response
echo You entered "%response%"

call :prompt "This is a prompt of a different length:" response
echo You entered "%response%"

<NUL set /P "=Press any key to exit. " & pause >NUL & echo;
goto :EOF

:prompt <question> <return_var>
setlocal disabledelayedexpansion
set "dots=................................................................................"
for /f "skip=4 tokens=2 delims=:" %%I in ('mode con') do if not defined cols (
    set /a cols = %%I - 4
)
call set "dots=%%dots:~-%cols%%%"
rem // credit: https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/AUXP8XbRAJA
for /f %%a in ('copy /Z "%~dpf0" nul') do endlocal & set /P "%~2=%dots%%%a%~1 " & exit /b
rojo
  • 24,000
  • 5
  • 55
  • 101
  • thank you ever so much!, just quickly, how could i keep the dots after i've deleted the characters on top of them? – Lewis Hughes Jun 02 '17 at 14:22
  • @LewisHughes Are you asking how to superimpose a character on top of another character so that both display at the same X,Y coordinate? The cmd console doesn't allow that. – rojo Jun 02 '17 at 14:30
  • 1
    @rojo I think he means: if you use the backspace when filling in the answer, is there a way of (re)filling the empty space with dots (again). `a .....` -> `ab ....` -> `a .....` instead of `a ....`. I think not. – TripeHound Jun 02 '17 at 14:32
  • @TripeHound Thanks for the translation. `:)` @Lewis, while the execution thread is waiting for user input, there is no output, nor is there a way in the Batch language to listen for a backspace as far as I'm aware. What you're asking has no easy solution. – rojo Jun 02 '17 at 14:35
  • okay, well i thank you for all your help, your a credit to this forum thank you @rojo – Lewis Hughes Jun 02 '17 at 14:36
  • and you too @TripeHound – Lewis Hughes Jun 02 '17 at 14:36
1

A minor variant on rojo's excellent answer. Instead of backspacing over the dots, this uses a carriage return (without line-feed) to output the prompt, the dots, CR and the prompt again:

@echo off
setlocal enabledelayedexpansion

REM From https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/AUXP8XbRAJA
for /f %%a in ('copy /Z "%~dpf0" nul') do set "\r=%%a"

set "DOTS=.................................................."
set "PROMPT=Fill in the blank: "

set /p "response=%PROMPT%%DOTS%!\r!%PROMPT%"

echo You entered "%response%".

Although, as rojo notes, the use of enabledelayedexpansion may cause problems if you use exclamation marks elsewhere. One solution would be to put this code in a "subroutine" (where I additionally pass in the variable to contain the response and the prompt):

@echo off
setlocal

call :getString answer "Fill in the blank: "
echo You entered "%answer%".
goto :eof

:getString
    setlocal enabledelayedexpansion

    REM From https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/AUXP8XbRAJA
    for /f %%a in ('copy /Z "%~dpf0" nul') do set "\r=%%a"

    set "DOTS=.................................................."
    set "PROMPT=%~2"

    set /p "response=%PROMPT%%DOTS%!\r!%PROMPT%"

    endlocal && set %1=%response%
    goto :eof

The last line (endlocal && ...) allows us to end locality (and delayed-expansion) while still using the value of an environment variable defined within that block).

(I was working on an alternative solution using the (now not standard, but easily available) choice command, to process the input character-by-character, but it doesn't look like it was going anywhere).

TripeHound
  • 2,721
  • 23
  • 37
  • Delayed Expansion will mangle exclamation marks. But I like the efficiency of the carriage return idea. – rojo Jun 02 '17 at 15:17
  • 1
    @rojo It appears delayed-expansion is necessary for the CR to work (`!\r!` works, `%\r%` does not). – TripeHound Jun 02 '17 at 15:31