2017-01-04 46 views
2

我想添加特殊字符如<|进入我的选择命令,我该怎么做?如何在选择命令中使用特殊字符 - 批处理文件

这里是我的旧代码:

CHOICE /C ABCDEFGHIJKLMNOPQRSTUVWXYZ0134567928 /N /M "Press 8 ...." 

,我想它是这样的:

CHOICE /C `~,.<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ0134567928 /N /M "Press 8 ...." 

任何帮助将不胜感激,谢谢。

编辑:由于你们中的一些人可能会问为什么我需要这么多的选择,我来这里回答。这是因为按无效的选择会给你一个恼人的嘟嘟,我不喜欢。所以我问了这个问题。

+1

您需要转义或引用特殊字符。如果你这样做,你会看到这条消息 - “有效的选择字符是:a-z,A-Z,0-9和ASCII值为128到254' –

+0

@Noddles uhm。这已在下面得到解答。 – SteveFest

+1

你是什么意思。你的代码是错误的(缺少三个双引号),所以我修复它以显示有关其他错误代码的错误消息。 MSDos'choice'采用转义键。 –

回答

4

CHOICE命令只允许使用字母数字字符,以及扩展ASCII字符和128-254之间的小数字节代码。

我已经写了一个基于使用REPLACE的hack的CHOICE的纯批量替换。我的:getKey例程可以接受大多数任何字符,并允许您指定允许的字符,并将捕获的字符放入您选择的变量中 - 比使用ERRORLEVEL更方便。

我最初在http://www.dostips.com/forum/viewtopic.php?f=3&t=7396上发布了例程。该链接还有一个更复杂的例程,它可以绝对读取任何键值,包括NULL,以及允许输入掩码字符串(对每个字符显示星号)的例程。

下面是:getKey例程,以及显示用法的示例。如果您希望密钥区分大小写,请移除/I开关。完整的文档嵌入在脚本中。

编辑 - 我已将代码更新至版本2。0能够指定提示,并使有效密钥列表区分大小写。 不能被仿真的唯一选择功能是具有默认响应的超时选项。我没有看到提供超时选项的合理方法。

@echo off 
setlocal enableDelayedExpansion 

set "valid=0`~,.<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ0134567928" 
call :getKey /p "Press 8 ...." key valid /i 
echo(
echo You pressed !key! 
exit /b 

::getKey [/P "Prompt"] KeyVar [ValidVar [/I]] 
:: 
:: Read a keypress representing a character between 0x00 and 0xFF and store the 
:: value in variable KeyVar. Null (0x00), LineFeed (0x0A), and Carriage Return 
:: (0x0D) will result in an undefined KeyVar. On Windows 10, Ctrl-Z (0x1A) will 
:: also result in an undefined KeyVar. The simplest way to get an undefined 
:: KeyVar is to press the [Enter] key. 
:: 
:: The optional /P parameter is used to specify a "Prompt" that is written to 
:: stdout, without a newline. Also, the accepted character is ECHOed after the 
:: prompt if the /P option was used. 
:: 
:: The optional ValidVar parameter defines the values that will be accepted. 
:: If the variable is not given or not defined, then all characters are accepted. 
:: If given and defined, then only characters within ValidVar are accepted. The 
:: first character within ValidVar should either be 0, meaning ignore undefined 
:: KeyVar, or 1, meaning accept undefined KeyVar. The remaining characters 
:: represent themselves. For example, a ValidVar value of 0YN will only accept 
:: uppercase Y or N. A value of 1YN will additionally accept [Enter] etc. 
:: 
:: If ValidVar is followed by the optional /I switch, then case of standard 
:: English letters is ignored. The case of the pressed key is preserved in 
:: the result, but English letters A-Z and a-z are not rejected due to case 
:: differences when the /I switch is added. 
:: 
:: Any value (except null) may be entered by holding the [Alt] key and pressing 
:: the appropriate decimal code on the numeric keypad. For example, holding 
:: [Alt] and pressing numeric keypad [1] and [0], and then releasing [Alt] will 
:: result in a LineFeed. 
:: 
:: The only way to enter a Null is by holding [Ctrl] and pressing the normal [2] 
:: 
:: An alternate way to enter control characters 0x01 through 0x1A is by holding 
:: the [Ctrl] key and pressing any one of the letter keys [A] through [Z]. 
:: However, [Ctrl-A], [Ctrl-F], [Ctrl-M], and [Ctrl-V] will be blocked on Win 10 
:: if the console has Ctrl key shortcuts enabled. 
:: 
:: This function works properly regardless whether delayed expansion is enabled 
:: or disabled. 
:: 
:: :getKey version 2.0 was written by Dave Benham, and originally posted at 
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=7396 
:: 
:: This work was inspired by posts from carlos and others at 
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=6382 
:: 
:getKey 
setlocal disableDelayedExpansion 
if /i "%~1" equ "/P" (
    <nul set /p ^"=%2" 
    shift /1 
    shift /1 
    set "getKey./P=1" 
) else (
    set "getKey./P=" 
) 
:getKeyRetry 
(
    endlocal&setlocal disableDelayedExpansion 
    (for /f skip^=1^ delims^=^ eol^= %%A in ('replace.exe ? . /u /w') do for /f delims^=^ eol^= %%B in ("%%A") do (
    endlocal 
    if "%%B" equ "" (set "%1=^!") else set "%1=%%B" 
    setlocal enableDelayedExpansion 
)) || (
    endlocal 
    set "%1=" 
    setlocal enableDelayedExpansion 
) 
    set "getKey./P=%getKey./P%" 
    if defined %1 (set "getKey.key=!%1!") else set "getKey.key=x" 
) 
(
    if "!%2!" neq "" (
    if defined %1 (
     set "getKey.mask=!%2:~1!" 
     if not defined getKey.mask goto :getKeyRetry 
     if /i "%~3" equ "/I" (
     if "!%1!" equ "=" (
      set "getKey.mask=a!getKey.mask!" 
      for /f "delims=" %%A in ("!getKey.mask!") do if /i "!getKey.mask:%%A=%%A!" equ "!getKey.mask!" goto :getKeyRetry 
     ) else for /f delims^=^ eol^= %%A in ("!%1!") do if "!getKey.mask:*%%A=!" equ "!getKey.mask!" goto :getKeyRetry 
    ) else (
     for /f tokens^=1*^ eol^=^%getKey.key%^ delims^=^%getKey.key% %%A in ("!getKey.mask!!getKey.mask!") do if "%%B" equ "" goto :getKeyRetry 
    ) 
    ) else if "!%2:~0,1!" equ "0" goto :getKeyRetry 
) 
    if defined getKey./P echo(!%1! 
    exit /b 
) 
+0

当我运行'nul set/p时,我得到了一个不正确的命令语法按下一个键[A |>]:“ ' – SteveFest

+2

@SteveFest,我想有一个'='符号缺失:']:”' – aschipfl

+0

@aschipfl - 谢谢。我实际上测试了代码,但是我把错误的版本粘贴到了答案中。所有固定。 – dbenham

2

使用选择,你不能。

如果您尝试使用无效字符执行Choice,您将收到一条消息。例如(尖 '^' 符号是为了躲避管 '|',因为这是CMD特殊字符):

CHOICE /C ^| 

回报:

错误:无效的选择。有效选项字符是:AZ,AZ,128到254

可能的解决方法的0-9和ASCII值:

您可以使用可能SET来完成你的需求,但你与变量工作批处理脚本可能会导致问题。任何你可以使用这些变量的地方,都需要使用转义字符符号(^)。

该解决方案还要求用户在做出选择后按Enter键。

@ECHO OFF 
Choose one: 
ECHO. 
ECHO ^| - 1 
ECHO ^> - 2 
ECHO A - 3 
ECHO ^" - 4 
ECHO ^^ - 5 
SET /P KeyPressed=Choice? [^|^>A] 
IF [^%KeyPressed%]==[^|] ECHO 1 && GOTO END 
IF [^%KeyPressed%]==[^>] ECHO 2 && GOTO END 
IF [^%KeyPressed%]==[^A] ECHO 3 && GOTO END 
IF [^%KeyPressed%]==[^"] ECHO 4 && GOTO END 
IF [^%KeyPressed%]==[^^] ECHO 5 && GOTO END 
ECHO None of them. 


:END 
+0

然后有没有解决这个问题的方法? – SteveFest

+1

更新了可能的解决方法? –

+1

太棒了!它像一个魅力一样工作! – SteveFest

-1
ShowMenu 

Sub ShowHelpMenu 
    outp.writeline " -----------------------------------------------------------------------------" 
    outp.writeblanklines(1) 
    outp.writeline " Menu" 
    outp.writeline " ----" 
    outp.writeblanklines(1) 
    outp.writeline " 1 Help    2 HTML Help   3 Version   4 History" 
    outp.writeblanklines(1) 
    outp.writeline " 5 Exit" 
    outp.writeblanklines(1) 
    outp.write "Filter>" 
End Sub 

'============================================= 
Sub ShowMenu 
    Do 
     ShowHelpMenu 
     Answ=Inp.readline 
     If Answ = "1" Then 
      ShowGeneralHelp "TEXT" 
     Elseif Answ = "2" Then 
      ShowGeneralHelp "HTML" 
     Elseif Answ = "3" Then 
      Version 
     Elseif Answ = "4" Then 
      History 
     Elseif Answ = "5" Then 
      Exit Do 
     End If 
    Loop 
End Sub 

Th9is是一个VBS文件。

+0

对不起,我想要一个批处理文件。你的回答是在VBS中。 – SteveFest

+0

我实际上已经修改了选择命令,并且我忘了添加引号。我正在处理另一件需要不断按下键盘的东西。我不认为'set/p'能够实现这一点。 – SteveFest

+0

为什么我会使用这么多的选项,因为我不希望它在选择无效选项时发出“哔哔”声** – SteveFest

相关问题