【问题标题】:Looping for every character in variable string BATCH循环变量字符串 BATCH 中的每个字符
【发布时间】:2013-02-06 22:16:55
【问题描述】:

我正在尝试遍历字符串中的每个字符。但是,我只知道如何使用以下内容循环字符串中的每个单词:

(set /P MYTEXT=)<C:\MYTEXTFILE.txt

set MYEXAMPLE=%MYTEXT%
for %%x in (%MYEXAMPLE%) do (
ECHO DO SOMTHING
)

如何将其配置为按字符而不是按单词工作?

【问题讨论】:

    标签: loops batch-file character


    【解决方案1】:

    这是遍历字符串中每个字符的简单直接的方法:

    @echo off
    setlocal ENABLEDELAYEDEXPANSION
    
    set /P mytext= < MYTEXTFILE.txt
    echo Line is '%mytext%'
    
    set pos=0
    :NextChar
        echo Char %pos% is '!mytext:~%pos%,1!'
        set /a pos=pos+1
        if "!mytext:~%pos%,1!" NEQ "" goto NextChar
    

    【讨论】:

    • 添加setlocal enabledelayed expansion 否则下一条评论将是“不起作用”;)(看在上帝的份上,删除mytext= 之间的空格)
    • @Stephan,谢谢。在我的系统上不需要“setlocal ENABLEDELAYEDEXPANSION”,但很好。我测试了带和不带空格的 SET,在我的系统上没有任何区别,而且我发现带空格的可读性更高。我想我已经有很多年没有真正打过球了。
    • 嗯?空格在cmd 中确实有所不同(set var = value 将变量%var&lt;space&gt;% 设置为&lt;space&gt;value)。您使用什么系统(扩展)?
    • @Stephan,是的,我知道。但是您是否使用 /P 选项测试了这种情况?显然那里的空间是允许的。所以,是的,对于蝙蝠程序员来说,由于通常的情况(正如你所指出的),空间看起来是错误的,但在其他语言中,我倾向于添加空间,所以按照当前的习惯这样做。意识到我的“错误”很惊讶它仍然完全有效,然后离开了空间(直到你提醒我它看起来有多奇怪)。给它一个测试。如果 /P 的空格给您带来问题,请告诉我哪个 Windows 版本。谢谢。
    • 可以肯定,我做过测试。空间确实很重要。我使用 Win10(版本 10.0.10586)和 Win7 Enterprise(版本 6.1.7601)。 (两者都没有任何扩展)。也从未听过你说的任何东西(不是说,你在撒谎。但如果有“不兼容”,我想知道)。 (注意:set /a 真的不关心空格 - 但那是 /a,而不是 /p 或普通的 set
    【解决方案2】:

    AFAIK,FOR 无法进行逐字符迭代 - 一种可能的解决方法是构建这样的循环:

    @ECHO OFF
    :: string terminator: chose something that won't show up in the input file
    SET strterm=___ENDOFSTRING___
    :: read first line of input file
    SET /P mytext=<C:\MYTEXTFILE.txt
    :: add string terminator to input
    SET tmp=%mytext%%strterm%
    :loop
    :: get first character from input
    SET char=%tmp:~0,1%
    :: remove first character from input
    SET tmp=%tmp:~1%
    :: do something with %char%, e.g. simply print it out
    ECHO char: %char%
    :: repeat until only the string terminator is left
    IF NOT "%tmp%" == "%strterm%" GOTO loop
    

    注意:问题标题表明您要循环遍历“变量字符串中的每个字符”,这表明输入文件仅包含一行,因为命令(set /P MYTEXT=)&lt;C:\MYTEXTFILE.txt 只会读取 C:\MYTEXTFILE.txt 的第一行。如果您想遍历文件中的所有行,则解决方案有点复杂,我建议您为此打开另一个问题。

    【讨论】:

    • 是的,这回答了我的想法,那就是我们不能识字。这也解释了为什么我的循环有效以及退出程序循环时存在的可能解决方案
    【解决方案3】:

    splitStr 子程序如下:

    • 将逐个打印出字符串中的每个字符
    • 无论延迟扩展的状态如何,都可以安全地调用
    • 没有超慢goto循环
    • 处理 CR 和 LF
    • errorLevel 设置为字符串中的字符数
    @echo off & setLocal enableExtensions disableDelayedExpansion
    (call;) %= sets errorLevel to 0 =%
    
    set "testStr=uncopyrightable"
    call :splitStr testStr
    if errorLevel 1 (
        >&2 echo(string is %errorLevel% char(s^) in length
    ) else (
        >&2 echo(empty string
        goto die
    ) %= if =%
    goto end
    
    :die
    (call) %= sets errorLevel to 1 =%
    :end
    endLocal & goto :EOF
    
    :splitStr string=
    :: outputs string one character per line
    setLocal disableDelayedExpansion
    set "var=%1"
    
    set "chrCount=0" & if defined var for /f "delims=" %%A in ('
        cmd /v:on /q /c for /l %%I in (0 1 8190^) do ^
        if "!%var%:~%%I,1!" neq "" (^
        echo(:^!%var%:~%%I^,1^!^) else exit 0
    ') do (
        set /a chrCount+=1
        echo%%A
    ) %= for /f =%
    
    endLocal & exit /b %chrCount%
    

    【讨论】:

    • 那是一些伏都教黑暗魔法...运行...并用 /n 依次回显每个字符。注意:这仅在您正确握住您的舌头时才有效。该示例的任何变化都将失败(见下文)。另外,我尝试修改脚本以为每个字符输出彩虹色......而且它很脆弱......如果没有换行符调用 :splitStr testStr REM 工作,我无法让它回显! ;调用 :splitStr "quotedtestStr" REM 不起作用! ;设置quotedtestStr="uncopyrightable" REM 不起作用! ;调用 :splitStr %quotedtestStr% REM 不起作用! ;
    猜你喜欢
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    相关资源
    最近更新 更多