Batch file decides that 4 > 39, How do I fix it?

后端 未结 3 1573
一整个雨季
一整个雨季 2021-01-24 22:36

Note: The file Default.txt contains one line with these three characters:1:X

    @echo off
    set r=0
    :: For loop retrieves lines of text f         


        
3条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-24 23:22

    When comparing numerics, don't enclose them in quotation marks.

    command: if "4" leq "39" echo hi
    output: (empty line)

    command: if 4 leq 39 echo hi
    output: hi

    The reason for that is that "4" is alphabetically after "39", so "4 is greater than "3. When comparing using quotation marks, the comparison is alphabetic, not numeric as you intended.

    You've got a few other problems with your script. Don't put labels within parenthetical code blocks. You need to find some other place to put :len and :space outside of the if statement where they currently live. Strictly speaking, :: is also label named :, not a substitute for rem. When using :: as a comment, avoid using it within parenthetical code blocks as well. Use rem instead. Also, indent your code to make it easier to ensure you've got the same number of ( as ). Let me ask you: which is more readable?

    option 1:

    ...
    :space
    :: This loop adds spaces to each string so they will all be 39 characters in length.
    if "%r%" LEQ "39" (
    :: Note that there is a mandatory space at the end of the following line.
    set _%ln%=!_%ln%! 
    set /a r=%r%+1
    goto space
    )
    set /a n-=1
    set /a ln+=1
    goto process
    ) else (
    endlocal
    set _1=%_1%
    )
    echo %_1%]
    pause >nul
    

    The else is a continuation of the if statement above it, right? Wrong! Properly indented, you'd see that it's part of an if statement much higher in the script.

    option 2:

        rem This loop adds spaces to each string so they will all be 39 characters in length.
    
        if "%r%" LEQ "39" (
            rem Note that there is a mandatory space at the end of the following line.
            set _%ln%=!_%ln%! 
            set /a r=%r%+1
            goto space
        )
    
        set /a n-=1
        set /a ln+=1
        goto process
    
    ) else (
        endlocal
        set _1=%_1%
    )
    echo %_1%]
    pause >nul
    

    I'll never understand why some people insist on left-justifying every line of code they write. It only makes things much more difficult to troubleshoot.


    You know, there are more efficient ways to repeat characters. Rather than looping, you could do variable substring extraction.

    set "spaces=                                                  "
    set "39spaces=%spaces:~-39%"
    

    If you want to get the length of a string, the fastest way I've found to do that is based on jeb's answer here:

    :length  
    setlocal enabledelayedexpansion
    if "%~2"=="" (set ret=0) else set ret=1
    set "tmpstr=%~2"
    for %%I in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
        if not "!tmpstr:~%%I,1!"=="" (
            set /a ret += %%I
            set "tmpstr=!tmpstr:~%%I!"
        )
    )
    endlocal & set "%~1=%ret%"
    goto :EOF
    

    Example usage:

    command: call :length len "The quick brown fox"
    command: echo %len%
    output: 19

    Even if you're getting the length of a 2000 character line, that loop still counts the length in only 13 iterations, rather than potentially thousands.

提交回复
热议问题