Reputation: 675
This is my TXT :
echo x 1. Enter x
echo x 2. Leave x
echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo:
set /p Menu= Enter number {1,2}:
if not '%Menu%'=='' set Menu=%Menu:~0,1%
if '%Menu%'=='1' goto ConvM
My txt is converted to *.bat at home and, when the batch runs, the center portion of the phrase "Enter number {1,2}:" is positioned exactly in the middle of the delimiter "x". Result as shown below :
x 1. Enter x
x 2. Leave x
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Enter number {1,2}:
My txt is converted to *.bat at the company where I work and, when the batch runs, it shows something offset as shown below :
x 1. Enter x
x 2. Leave x
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Enter number {1,2}:
I converted my txt also to CMD but the result is the same. At home I have a Windows XP and at work I have Windows 7.
What should I do to have the "Enter number {1,2}:" centralized with the "x" in any computer?
Upvotes: 4
Views: 1606
Reputation: 130839
Unfortunately, Windows 7 (and I think Vista as well) ignores leading white space in a SET /P
prompt. Whitespace characters include space, tab, and non-breaking space (0xFF).
The solution is not intuitive, but it is simple. Just prefix your prompt with a backspace (0x08) character. The code below programmatically defines a variable containing a backspace character. It is then easy to include it in any propmpt as needed.
@echo off
setlocal
::Define a BS variable containing a backspace (0x08) character
for /f %%A in ('"prompt $H & echo on & for %%B in (1) do rem"') do set "BS=%%A"
echo x 1. Enter x
echo x 2. Leave x
echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo:
set /p Menu=%BS% Enter number {1,2}:
Normally a backspace will cause the line cursor to back up one position, and then the next character will overwrite what was there. But since the prompt always starts at the first position, there is no room to back up one. The backspace effectively does nothing accept allow for leading white space in your prompt :-)
You can put another character in front of the backspace if you want, but it is not needed. The backspace will back the line cursor up one position, and then your desired prompt will overwrite the unwanted character.
set /p Menu=x%BS% Enter number {1,2}:
EDIT - Here is an explanation of the FOR /F
line that defines the BS variable
The PROMPT
command controls the text that appears as a prefix of each line of output when ECHO is ON. By default it is the current directory followed by the >
character.
Using PROMPT $H
causes the prompt to be <backspace><space><backspace>
. So a command like REM
will result in output of <backspace><space><backspace>REM
.
There is a string of commands on one line that is executed. Normally commands are not echoed if they appear on the same line that issues the ECHO ON. The exception to that rule is any command that appears as part of a FOR DO clause is echoed. That is why the REM command is "executed" within a FOR loop - so we get the output of the REM command.
The entire string of commands is executed within an outer FOR /F
loop. The string is enclosed in single quotes to tell FOR /F
to execute a command. Within the single quotes the string is enclosed within double quotes. The double quotes protect the command concatenation &
operator. Normally a string of commands cannot be enclosed in double quotes. But it works in this case because of how FOR /F
works. The commands are executed implicitly via CMD /C "command string"
. So it is perfectly acceptable in this case to use the double quotes.
If double quotes are not used then the &
characters must be escaped with ^
:
('prompt $H ^& echo on ^& for %%B in (1) do rem')
Finally, since the default FOR /F DELIMS
is <tab><space>
, the output of the REM command will be parsed into tokens, and only the first token is preserved. The end result is BS value consisting of a single <backspace>
character.
Upvotes: 4