为什么提示用户输入字符串/选项后字符串比较无法按预期工作?

2023-12-07

除了空格和不需要的百分号之外,这是编写这些批处理代码行的正确方法吗?

:name
cls
echo now that we've got your color figured out, what about your name?
echo simply type the name you want for your character into the space below
echo (6 char max)
echo.
set /p %player% =

cls
echo so you want your name to be %player% ?
echo.
echo 1) yes
echo 2) no

set /p %namechoice% =
if %namechoice% == 1 goto check
if %namechoice% == 2 goto name


:check
if /I %player% == %username% (goto gamestart) else goto suprise

:suprise

批量用户输入玩家姓名后,不输出玩家姓名。

以及字符串比较check and name也不工作。

命令行if %namechoice% == 1 goto check导致批处理文件执行中断并显示错误消息:

goto这个时候是出乎意料的。


主要错误是一个简单的语法问题:

环境变量的定义只需指定变量名称,不带百分号,且等号前不带空格字符。

所以错误的是

set /p %player% =
set /p %namechoice% =

因为这两行在真正执行命令之前的预处理阶段被扩展SET to

set /p  =
set /p  =

如果有环境变量player and namechoice尚未定义。看为什么在命令行上使用“set var = text”后没有带有“echo %var%”的字符串输出?有关如何定义环境变量的详细信息,请参阅权利。它还解释了为什么变量定义上等号左边的空格字符成为变量名称的一部分,而批处理文件编写器几乎总是不需要它。

在运行批处理文件时可以很容易地看到这种简单的语法问题without @echo off在批处理文件的顶部或将此行修改为@echo on或注释掉::@echo off(无效标签)或rem @echo off(注释命令)从命令提示符窗口中输入批处理文件的名称(带双引号的完整路径),而不是双击批处理文件。

有何不同?

  1. With @echo off命令行是not在真正执行它们之前进行预处理(扩展环境变量)后打印到控制台窗口。这是批处理文件开发完成后所需的行为。但在批处理文件的开发和测试过程中,最好显示 Windows 命令解释器实际执行的内容,以发现编码错误。

  2. 双击批处理文件时cmd.exe开始使用选项执行批处理文件/C用于在批处理文件执行终止时自动关闭控制台窗口,无论执行成功还是错误。这使得无法看到 Windows 命令解释器输出的语法错误等导致立即退出批处理文件执行的情况。因此,建议在批处理文件开发期间从手动打开的命令提示符窗口中运行它,如此例所示cmd.exe以选项开始/K即使批处理完成后也保持控制台窗口打开,除非批处理文件使用命令exit不带参数/B。这使得还可以查看导致批处理意外退出的错误的错误消息。

稍后,当批处理文件按预期工作时,第一行可以是@echo off再次,当然可以通过双击来启动批处理文件。但在批处理文件开发过程中,最好始终在命令提示符窗口中运行批处理文件。向上/向下箭头键可用于滚动输入的字符串列表,这使得还可以轻松地重新输入例如玩家姓名。

以下是重写的批处理代码,其中包含一些改进和注释:

@echo off
setlocal EnableExtensions EnableDelayedExpansion

rem Define a too long player name before prompting the user for the player
rem name. This too long player name is kept in case of user hits just the
rem key RETURN or ENTER without entering anything at all. Then test for
rem entered name has not more than 6 characters. Delayed expansion is used
rem as the user could enter characters like " ! % ... which would in further
rem batch code execution result in exiting batch processing because of syntax
rem error or in unexpected behavior on referencing player name with expansion
rem before running the command.

:PromptForName
cls
echo Now that we've got your color figured out, what about your name?
echo Simply type the name you want for your character into the space
echo below (6 char max).
echo/
set "Player=No name entered"
set /P "Player=Player name: "
if not "!Player:~6!" == "" goto PromptForName

echo/
echo/
echo    1) yes
echo    2) no
echo/
choice /C:12 /N "So you want your name to be !player!? "
if errorlevel 2 goto PromptForName

if /I "!player!" == "%USERNAME%" goto GameStart

echo Surprise
endlocal
goto :EOF

:GameStart
echo/
echo Okay !Player!, let's play^^!

rem Wait 3 seconds using PING instead of TIMEOUT before exiting the
rem batch file because the command TIMEOUT does not exist on Windows XP.
%SystemRoot%\System32\ping.exe 127.0.0.1 -n 4 >nul

endlocal

The comment at top explains why the environment variable Player is defined with value No name entered. The batch user has the freedom to hit just RETURN or ENTER without entering anything at all or hits by mistake one of those 2 keys before entering a name. In this case the environment variable Player is either still not defined if not defined before, or it keeps its current value if already defined before. It is not good if the user enters nothing and the environment variable Player is not defined in this case. Therefore the player name is predefined with an invalid name.

输入的玩家姓名的长度也经过测试是否太长。

用户输入的字符串可能包含批处理语法关键字符,例如双引号、百分号、重定向运算符字符(尖括号、管道)、与号或启用延迟扩展的感叹号。为了防止在命令行执行之前使用环境变量扩展时输入的玩家名称出现语法错误而导致批处理退出,环境变量Player随处引用,并在批处理文件顶部启用延迟扩展。

要打印空行,最好使用echo/代替echo.因为echo.可能会失败并且速度会慢一点,因为 Windows 命令解释器会搜索与模式匹配的文件echo.*如 DosTips 论坛文章中所述回声。无法给出文本或空行 - 而是使用 ECHO/.

命令CHOICEset /P VariableName=Prompt text如果用户必须输入特定的键。命令CHOICE不允许用户输入批处理文件编写器不需要的内容,因此对于选择菜单来说更安全。

当前用户的帐户名引用%USERNAME%还可以包含空格字符。因此,强烈建议将包含的整个字符串括起来%USERNAME%始终用双引号引起来。

"%USERNAME%"字符串比较的右侧要求左侧的字符串也用双引号括起来,因为命令IF比较两个字符串并包含双引号。

由于这个原因,条件

if /I !player! == "%USERNAME%"

仅当批处理文件用户输入带双引号的玩家名称时才为真,这是不太可能的。左侧也必须使用双引号。

用双引号括起来或不用双引号括起来的两个比较字符串周围的空格字符数并不重要。

在命令提示符窗口中执行以下批处理文件

@echo on
@setlocal EnableExtensions EnableDelayedExpansion
@set "Player=<|>"
if /I "!Player!"=="%SystemRoot%" echo Strings are equal.
if /I "!Player!"  ==  "%WinDir%" echo Strings are equal.
if /I   "!Player!" ==  "%Player%" echo Strings are equal.
if /I "!Player!"==   "!Player!" echo Strings are equal.
if   /I   !Player!  ==  !Player! echo Strings are equal.
@endlocal

结果输出

if /I "!Player!" == "C:\WINDOWS" echo Strings are equal.

if /I "!Player!" == "C:\WINDOWS" echo Strings are equal.

if /I "!Player!" == "<|>" echo Strings are equal.
Strings are equal.

if /I "!Player!" == "!Player!" echo Strings are equal.
Strings are equal.

if /I !Player! == !Player! echo Strings are equal.
Strings are equal.

可以看到比较运算符周围有空格字符==与命令的执行无关IF。 Windows 命令处理器在执行之前对命令行进行漂亮的格式化IF命令。

但是要比较的字符串中的空格字符需要使用双引号,否则很可能会由于批处理文件执行时出现语法错误而导致批处理退出。

Note:等于运算符==命令的IF与赋值运算符的处理方式不同=命令的SET。不要混合它们。

为了了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • choice /?
  • cls /?
  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • ping /?
  • rem /?
  • set /?
  • setlocal /?

另请参阅 Microsoft 文章使用命令重定向运算符的解释>nul.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么提示用户输入字符串/选项后字符串比较无法按预期工作? 的相关文章

  • 根据文件内容重命名文件批处理文件

    我需要一个批处理文件来读取 XYZ txt 文件中存在的描述名称 并根据描述名称重命名该文件名 例如 我有一个名为 nest txt 的文件名 当我们打开文本文件 nest txt 时 文件名的第二行有说明 Description Man
  • 如何在批处理中返回数组的元素?

    我的程序中的数组列表中有两个元素 如何将变量分配给等于其中一个元素 这是代码 echo off setlocal enabledelayedexpansion set p string for l a in 0 1 1000 do if n
  • Windows批处理文件:在for循环中设置变量

    我有许多具有相同命名方案的文件 作为示例 四个文件分别称为 num 001 001 txt num 002 001 txt num 002 002 txt num 002 003 txt 第一组数字代表它来自哪个 包 第二组数字只是用来区分
  • Windows批量编程中读取文件名

    我想在Windows批处理编程中读取文件的名称 我尝试使用不同的方法但失败了请帮助 下面给出了场景 我的文件夹中有不同的文件 但所有文件的文件名长度相同 例如 1000342578 30062011 PDF 1000342329 30062
  • shell进程的并行执行

    有没有一个工具可以在 Windows 批处理文件中并行执行多个进程 我发现了一些有趣的 Linux 工具 parallel http mi eng cam ac uk er258 code parallel html and PPSS ht
  • Windows 批处理文件:如何启用命令的内联回显

    如果在 Windows 批处理文件中默认禁用 echo 是否有办法为特定命令 内联 启用它 我知道可以回显特定命令disabled通过在命令前添加 但是有没有办法做相反的事情呢 例如 假设有一个像这样的批处理文件 echo off cmd1
  • 如何在批处理文件中测试当前驱动器号?

    我正在尝试编写一个批处理文件 该文件获取运行批处理文件的驱动器号 并使用它的 IF 语句 例如如果字母是M 则会跳转到标签 mSection 这可能吗 您可以使用 d0 来获取驱动器号 像这样的东西 IF d0 M CALL mSectio
  • 如何使用 Windows 命令行环境查找和替换文件中的文本?

    我正在使用 Windows 命令行环境编写批处理文件脚本 并希望用另一个文件 例如 BAR 更改文件中某些文本 例如 FOO 的每次出现 最简单的方法是什么 有内置函数吗 这里的很多答案都帮助我指明了正确的方向 但是没有一个适合我 所以我发
  • 需要帮助通过批处理文件添加注册表项

    我正在尝试通过cmd添加以下注册表项 我无法让其他用户能够使用以下命令添加此注册表项regedit exe s Location Project reg HKEY CURRENT USER Software Autodesk Fabrica
  • 午夜后时间设置不正确

    我使用以下命令以更易读的格式获取当前日期 时间 set day date 4 2 set mth date 7 2 set yr date 10 4 set hur time 0 2 set min time 3 2 set bdate d
  • 回显 unicode 字符

    我想通过运行bat 文件在cmd 中回显unicode 字符 我准备了一个简短的脚本 echo off SET message G p3 echo message pause 我怎样才能做到这一点 是否可以直接将这封信放入代码中 这样做 两
  • 如何在后台运行python程序以保持活动窗口相同

    我编写了一个程序 可以将前景窗口更改为显示器尺寸的 85 并且要成功运行 前景窗口需要保持不变 我已将 python 脚本 pyw 放入批处理文件 运行 pythonw 并在桌面上创建了批处理文件的快捷方式 并提供了快速运行它的快捷方式 我
  • 已安装全局 NPM 包但未找到命令

    我已经全局安装了两个 npm 包 下载 https www npmjs com package download and 谜虚拟盒 https www npmjs com package enigmavirtualbox通过命令行 npm
  • 在Java中运行bat文件并等待

    您可能会认为从 Java 启动 bat 文件是一项简单的任务 但事实并非如此 我有一个 bat 文件 它对从文本文件读取的值循环执行一些 sql 命令 它或多或少是这样的 FOR F x in CD listOfThings txt do
  • 批处理文件删除目录中除指定列表之外的所有文件夹

    我正在寻找一个批处理文件 该文件将进入 C Documents and Settings 并删除除我想保留的几个文件夹之外的所有文件夹 这是一个破解方法 D 如果您在folders txt 中有一个文件夹路径列表 如下所示 C Docume
  • 我可以从命令行或 MS-Dos 启用/禁用网络连接吗?

    我想从 Windows 8 中的命令行启用 禁用网络连接 netsh interface set interface Local Area Connection DISABLED 要启用该接口 您需要运行 netsh interface s
  • 围绕 readline 构建的 python 批处理的触发器选项卡完成

    背景 我有一个 python 程序 它导入并使用 readline 模块来构建自制的命令行界面 我有第二个 python 程序 围绕 Bottle 一个 Web 微框架构建 充当该 CLI 的前端 第二个 python 程序向第一个程序打开
  • 为什么批处理文件中的 RMDIR 作为最后一个命令没有删除文件夹?

    我的 bat 文件中有以下代码 echo off xcopy Y S CD Code Release C Users USERNAME Desktop ShareIt I cls cd C Users USERNAME Desktop Sh
  • 批处理文件:FOR 循环中的 GOTO

    我有一个带有 FOR 循环的批处理文件 在循环中 我必须等待进程结束 为此我使用了 IF 和 GOTO 问题是 GOTO 打破了循环 我尝试寻找其他解决方案 但没有找到任何东西 如何做呢 echo off for f tokens a in
  • 为什么 C# ProcessStartInfoRedirectStandardOutput 会导致 xcopy 进程失败

    这有点痛苦 因为我现在没有代码 但我会尽力解释 我有一个简单的 C 应用程序 它启动 Ruby 脚本 它还执行一些其他操作 因此它生成一个批处理文件并执行该文件 我正在使用 C 进程对象并设置以下内容 重定向标准输出 true 重定向标准错

随机推荐

  • 迭代对象时如何断言匹配类型?

    以下代码块会产生打字稿错误 因为尽管we我知道foo k and bar k 是同一类型 TS 无法知道 好吧 也许通过某种魔法它可以 但显然它不知道 interface IMixed a number b string c boolean
  • 从 Web 服务访问 FacesContext

    我正在开发一个 Web 服务 该服务将由我编写的客户端调用 在 Web 服务中 我需要使用应用程序范围的对象 以减轻系统上应用程序的负载 我已经实现了我的应用程序范围的对象 如下所示这个问题 我可以在 jsf 页面中使用我的对象 没有任何问
  • 有 GZIP J2ME 库吗? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 是否有适用于 J2ME 的 gzip 压缩库 Try Jazzlib 虽然是GPL 而且好像已经有一段时间没有更新了 另一种选择是尝试从libgcj
  • XSLT 模板中的超链接

    我正在尝试使用 XML 信息和 XSLT 模板创建超链接 这是 XML 源
  • php preg_replace 特定 html 注释标签之间的所有内容

    我检查了其他答案 但似乎无法执行以下操作 请帮助别人 我想删除中间的所有内容 包括特定的 html 注释 HTML Some HTML that must stay some html that must go Some more HTML
  • 将 opencv 重映射代码从 c++ 转换为 python

    我正在尝试将 c opencv cv2 remap 代码转换为 python 我没有收到任何错误 但结果不符合预期 我得到了缩放图像 c code int main Mat img imread captcha1 jpg float pha
  • Angular:ng-repeat 不起作用

    这是我的代码 我从 w3school 获取的
  • ViewScoped 的工作方式与 RequestScoped 类似 - 为什么?

    我编写了一个 ViewScoped Managed Bean 每次刷新 Web 浏览器中的页面时 该 Managed Bean 似乎都被重新创建 文章为空 它加载一个新的文章对象等等 对我来说 它看起来与 RequestScoped 的行为
  • 在 Windows 7 调试指令中有效的循环语句在 DOSBox 0.74 中不起作用

    我们有一个关于汇编语言循环的活动 我们的任务很简单 显示数字 0 到 9 每个数字之间有空格 我在我们学校的 WINDOWS 7 中使用 debug 命令获得了可以在命令提示符下运行的代码 我的笔记本电脑是 Windows 10 最近我发现
  • 如何在 JavaScript 中使用 C# 枚举值

    我有一个 C 枚举 即类似于 Category cs 的东西 在下拉列表中 我们绑定值 因此 如果用户在下拉列表中选择某个特定值 它将隐藏一个 div 所以我想获取javascript中的枚举值 即想将枚举值与javascript中的一个选
  • 如何在不创建 GLSurfaceView 的情况下检测 OpenGL 功能 (Android)

    在决定是否使用 OpenGL 还是 Canvas 进行图形处理之前 我尝试访问手机的 OpenGL 功能 但是 我可以阅读文档的所有功能都要求您已经拥有有效的 OpenGL 上下文 即 创建一个 GLSurfaceView 并为其分配渲染
  • 让函数按非内置类型的 const 值返回的用例有哪些?

    最近我读到 从函数返回值来限定非内置类型的返回类型 const 是有意义的 例如 const Result operation do something return Result 我正在努力理解这样做的好处 一旦返回对象 调用者肯定会选择
  • .Net 图表 - 具有不同间隔的 X 轴 [重复]

    这个问题在这里已经有答案了 我正在使用 Net 图表 其中 我显示了间隔为 28 天的折线图 这是我的代码 Chart1 ChartAreas ChartArea1 AxisX IntervalOffset 1 Chart1 ChartAr
  • 嘲笑GAE开发服务器?

    我正在尝试在我的开发 GAE 服务器上模拟 HTTPServletRequest 数据 我正在运行 Eclipse 插件 1 3 7 我尝试这样做 package com FOO madservice servlet mock import
  • JAVAFX 11 不支持 ECMAScript6 和 css3

    我正在使用 JAVA FX 11 的一些绘图工具创建一个网页浏览exp 但是在尝试加载具有以下功能的javascript代码时let and const使用这些变量只是被忽略并抛出异常 我使用的是 Maven 3 8 0 Java 1 8
  • PHP:gettext 需要 LC_MESSAGES 目录吗?

    为了翻译我的 PHP 应用程序 我使用在 gettext 模块中编译的方法 这是根据文档制作的翻译目录树 locale cs CZ LC MESSAGES messages po messages mo de DE LC MESSAGES
  • 如何显示等待 gif 直到图像完全加载

    大多数流行的浏览器在渲染图像时 会在加载时从上到下逐行显示图像 我有一个要求 即在加载图像时应显示等待 gif 当图像完全加载时 应该显示它而不是等待 gif 你可以使用 jQueryload method 你可以看这里 http jque
  • BAT 文件:打开新的 cmd 窗口并在其中执行命令

    我正在尝试在 BAT 文件中打开一个新的命令窗口 start windir system32 cmd exe 打开后 我想在新窗口中执行 BAT 命令 echo test in new window 我怎样才能做到这一点 您可能已经找到了答
  • 用Activity实现OnClickListener有什么效果?

    我不明白为什么我必须实现 OnClickListener 才能使用 OnClick 方法 假设这段代码 public class KlickitestActivity extends Activity implements OnClickL
  • 为什么提示用户输入字符串/选项后字符串比较无法按预期工作?

    除了空格和不需要的百分号之外 这是编写这些批处理代码行的正确方法吗 name cls echo now that we ve got your color figured out what about your name echo simp