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

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(使用前将#替换为@)

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

  • 小于或等于

    使用暂停命令我发现错误位于此代码的第一行 if choice 1 if energy gt m2enc set a enemhp enemhp m1hpd earmr pause set a energy energy m1enc set
  • 为什么 C# ProcessStartInfoRedirectStandardOutput 会导致 xcopy 进程失败

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

    我有一个 VBScript 应该运行 bat 或 vbs 文件 但它不起作用 它出现一个错误 指出无法找到该文件 无论我是否放入文件路径 我认为这并不重要 因为它位于同一目录中 所以我的问题是 如何从 VBScript 中启动 bat 文件
  • 如何编写 .bat 或 .cmd 文件来从 PATH 中删除元素?

    Related 如何列出批处理文件中路径的元素 https stackoverflow com questions 1424558 FOR 是如何运作的 https stackoverflow com questions 817280 ho
  • 在 C# 中编写批处理脚本的好方法是什么?

    我想用 C 编写简单的脚本 我通常会使用 bat 或 4NT btm 文件 复制文件 解析文本 询问用户输入等等 相当简单 但在批处理文件中正确执行这些操作确实很困难 例如没有例外 我熟悉像 AxScript 这样的命令行 脚本 包装器 这
  • 如何获取分配给循环内处理的环境变量的逗号分隔字符串的每一项?

    The FOR循环仅输出列表的第一项 我正在尝试遍历整个列表 ECHO OFF set list this is a list FOR f tokens 1 delims a IN list DO echo a pause The FOR
  • 使用“for”循环迭代目录中的所有文件

    如何使用 a 迭代目录中的每个文件for loop 我如何判断某个条目是目录还是文件 这会递归地列出当前目录及其子目录中的所有文件 并且仅列出文件 for r i in do echo i 此外 如果您在批处理文件中运行该命令 则需要将 符
  • 如何对 NT 批处理文件中的空格进行 URL 编码?

    我很不幸地使用了一个程序 该程序要求传递给它的所有文件名都是有效的 URL 不 我不知道为什么 而不是必须下降到命令行并手工制作file 每次 我都会将 URL 放在一起生成一个批处理文件 我可以简单地将从 Windows GUI 拖动的文
  • 批量检测系统是32位还是64位

    有谁知道如何创建一个批处理文件 如果是 64 位系统 可以对一个程序进行 shell 处理 如果是 32 位系统 则可以对另一个程序进行 shell 处理 检查 PROCESSOR ARCHITECTURE being x86 if PRO
  • 从某个文件夹启动随机批处理文件

    问题是这样的 我有一个名为 abc 的文件夹 其中包含几个批处理文件 它们的命名如下 abc1 batabc2 batabc3 batabc4 bat 等等 我需要一个脚本 当我单击它时 它会随机启动其中一个批处理文件 我需要的脚本将存储在
  • 将目录添加到path环境变量

    我的要求是将目录之一添加到path安装我的应用程序时 Windows 中的环境变量并将其删除path使用批处理文件卸载时的环境变量 在与此相关的 stackoverflow 答案之一中 建议将目录添加到路径环境变量中 setx path C
  • 如何查找具有特定模式的文件夹和文件

    我想编写一个批处理文件 该文件将写入日志包含特定模式以及排除文件夹的所有文件和文件夹 但没有成功 ECHO OFF for r c x in david do echo x findstr f exclude txt c x gt nul
  • 如何通过批处理脚本检查进程是否正在运行

    如何检查应用程序是否正在从批处理 以及 cmd 文件运行 如果程序已经在运行 我不需要启动另一个实例 我无法更改应用程序以使其仅作为单个实例 该应用程序还可以以任何用户身份运行 我想到的另一种可能性 不需要保存文件 灵感来自于使用grep
  • 如何使用批处理文件将多个命令插入到批处理文件中

    我正在制作一个批处理文件 我们称之为 Create bat 它将创建一个批处理文件 我们称之为 Created bat 该文件将在其中插入多个命令 其中一条命令如下 FOR F x IN tasklist NH FI IMAGENAME e
  • Windows Batch 帮助从命令输出设置变量[重复]

    这个问题在这里已经有答案了 我需要运行一个简单的 find 命令并将输出重定向到 Windows 批处理文件中的变量 我已经尝试过这个 set file ls find txt echo file 但这不起作用 如果我运行此命令 它可以正常
  • 在批处理文件中添加 +1 到日期

    我有一个批处理文件 可以很好地创建今天的日期 现在我需要更新它以显示明天的日期 任何帮助深表感谢 echo off set TimeStamp 12 00 00 FOR F TOKENS 1 DELIMS A IN DATE T DO SE
  • 我应该如何传递密码(包含特殊字符)作为命令行参数?

    我有一个部署脚本 必须将 LDAP 密码作为命令参数传递给该脚本 实际密码 foo ser ver 1 包含三个空格字符 开头 之前1 之后1 e g bin gt deployment bat LDAPPassword foo ser v
  • 从目录获取第一个文件名的批处理脚本

    我的函数需要特定目录中的第一个文件名来使用第一个文件处理一些测试 完成测试后从目录中删除第一个文件 我尝试如下 FOR R
  • 批处理文件搜索与本地文件同名的文件夹并将所述文件移动到找到的文件夹不起作用

    因此 我尝试创建一个批处理文件 该文件将在与批处理文件相同的目录中获取 pdf 文件并输出文件名 无扩展名 我使用这段代码来完成此任务 echo off for r C Users me Test Folder G in pdf do se
  • .bat 文件将文件排序到文件夹中

    对于我的图片集 我希望文件夹中的所有图片按日期自动分类到文件夹中 幸运的是 这些文件已经以时间戳命名 2012 07 15 12 21 06 jpg 2012 07 15 12 21 26 jpg 2012 07 16 12 12 50 j

随机推荐

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

    以下代码块会产生打字稿错误 因为尽管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