Board logo

标题: 【练习-016】批处理判断字符串长度 [打印本页]

作者: 523066680    时间: 2008-8-14 07:49     标题: 【练习-016】批处理判断字符串长度

呵呵大家也看到题目--基础练习。我不会出的太难的,这道题的思路应该会比较多的
不过我也还没开始做,希望大家积极参与哦。(最惨的就是只能加别人两分,郁闷)
习题1.1 字符串长度不超过80。不含特殊字符
             例 i like the bathome,because here is the batch of the world.
       1.2 字符串长度小于255,含有特殊字符,试求其长度。
            例 %%a%%!ver!&^^^ ^*~                     are you o                 k ?" : \  / ` `  verfdxcweippo opj x ds gw !%%
一般的,先求1.1的题目。看谁的代码灵活、简洁、思路清晰。然后再做1.2


(汗。中文不用考虑……)
其实我也是想征集一个比较好的办法……估计如果有中文的话。或许可以重定向到文本然后再判断字节吧。我猜可以的。

最后:一题多解,可别只用 重定向文本 那个方法哈。

[ 本帖最后由 batman 于 2008-8-25 14:19 编辑 ]
作者: pusofalse    时间: 2008-8-14 08:10

感觉这题不是基础练习。
作者: 523066680    时间: 2008-8-14 08:20

额……感觉也是哦……不过重定向文本的方法很简便。(我觉得这个方法可能可以解决那个--三列对齐的问题)
别的方法就麻烦喽。
给个生成文本的。
  1. @echo off
  2. echo,i like the bathome,because here is the batch of the world.>x.x
  3. for /f "tokens=*" %%a in ('dir x.x /-c ^|find " 字节" ^|find /v ":"') do (
  4. for /f "tokens=3" %%b in ('echo,%%a') do (
  5. set /a n=%%b-2
  6. call echo %%n%%
  7. del x.x
  8. )
  9. )
  10. pause>nul
复制代码

[ 本帖最后由 523066680 于 2008-8-14 09:06 编辑 ]
作者: pusofalse    时间: 2008-8-14 08:31

*********************
屏蔽,看错题意。

[ 本帖最后由 pusofalse 于 2008-8-14 09:11 编辑 ]
作者: a794685135    时间: 2008-8-14 20:18

- -!

到底是判断i like the bathome,because here is the batch of the world.这段话里面除了空格之外还有多少个字符,还是判断这个保存为文本后有多大?
作者: shqf    时间: 2008-8-15 07:16

先1.1题,1.2题有点难度呵:
  1. @echo off
  2. set str=i like the bathome,because here is the batch of the world.
  3. :count
  4. if "%str%"=="" (echo %n%) else (set /a n+=1&set str=%str:~1%&goto count)
  5. pause
复制代码

[ 本帖最后由 shqf 于 2008-8-15 07:19 编辑 ]
作者: pusofalse    时间: 2008-8-15 08:00

1.2题果真有点难度。
从文本中取值还好,但直接给定一字符串,大概只能就题解题了。
作者: Batcher    时间: 2008-8-15 08:39

1.1
  1. @echo off
  2. set str=i like the bathome,because here is the batch of the world.
  3. for /f "skip=1 delims=:" %%a in ('^(echo "%str%"^&echo.^)^|findstr /o ".*"') do set /a length=%%a-5
  4. echo %length%
复制代码

作者: Batcher    时间: 2008-8-15 08:42

1.1
  1. @echo off
  2. echo "i like the bathome,because here is the batch of the world.">"%temp%\_strlen.txt"
  3. for %%a in ("%temp%\_strlen.txt") do set length=%%~za
  4. set /a length=length-4
  5. echo %length%
复制代码

作者: 523066680    时间: 2008-8-15 09:23

哈 又学到了东西 感谢前辈们!

[ 本帖最后由 523066680 于 2008-8-15 09:26 编辑 ]
作者: batman    时间: 2008-8-15 09:54

1.1:
  1. @echo off
  2. set "str=i like the bathome,because here is the batch of the world."
  3. set "num=80"
  4. :lp
  5. set "str=%str%0"&set /a num-=1
  6. if "%str:~79,1%" neq "0" goto lp
  7. echo 字符个数为%num%个&pause>nul
复制代码
  1. @echo off
  2. echo i like the bathome,because here is the batch of the world.>1.txt&echo.>>1.txt
  3. for /f "delims=:" %%i in ('findstr /o .* 1.txt') do set "num=%%i"
  4. set /a num-=2&del /q 1.txt
  5. echo 字符个数为%num%个&pause>nul
复制代码

[ 本帖最后由 batman 于 2008-8-15 10:00 编辑 ]
作者: batman    时间: 2008-8-15 10:08

1.2:
  1. @echo off
  2. set "str=%%a%%!ver!&^^^ ^*~                     are you o                 k ?" : \  / ` `  verfdxcweippo opj x ds gw !%%"
  3. setlocal enabledelayedexpansion
  4. set "num=255"
  5. :lp
  6. set "str=!str! "&set /a num-=1
  7. if "!str:~254,1!" neq " " goto lp
  8. echo 字符个数为%num%个&pause>nul
  9. pause>nul
复制代码

[ 本帖最后由 batman 于 2008-8-15 10:09 编辑 ]
作者: shqf    时间: 2008-8-15 15:20

  1. ::%%a%%!ver!&^^^ ^*~                     are you o                 k ?" : \  / ` `  verfdxcweippo opj x ds gw !%%
  2. @echo off&setlocal enabledelayedexpansion
  3. set /p str=<%0
  4. for /l %%a in (1,1,255) do (set str=!str:~1!&if "!str!"=="" (set /a totle=%%a-2&echo !totle!&goto end))
  5. :end
  6. pause
复制代码
应该是111个字符吧,上楼的结果怎么是108呀?

[ 本帖最后由 shqf 于 2008-8-15 15:28 编辑 ]
作者: Batcher    时间: 2008-8-15 15:44     标题: 回复 13楼 的帖子

12楼在第一次set的时候,脱掉了三个百分号。
作者: Batcher    时间: 2008-8-15 15:49

13楼的方法不错,我也这样写过,但缺点在于很难作为一个函数或者模块放到一个大的批处理里面,缺乏实用性,不知道 shqf 兄有没有好的方法?
作者: 愚无尽    时间: 2008-8-15 20:01

很有研究的说,很热闹。
作者: shqf    时间: 2008-8-15 21:11

含特殊字符的字符串赋值让我很头痛,batman版主的方法也不错,是我以前所不知道,学习了。其思路也让我看了代码好久,才知奧妙所在。
作者: pusofalse    时间: 2008-8-16 07:34

这是我最初的解,只能就题解题而已。
  1. @echo off&setlocal enabledelayedexpansion
  2. set "str=i like the bathome,because here is the batch of the world. "
  3. call :loop
  4. endlocal
  5. set "str=%%a%%!ver!&^^^ ^*~                     are you o                 k ?" : \  / ` `  verfdxcweippo opj x ds gw !%%"
  6. setlocal enabledelayedexpansion
  7. set "str=!str:%%=%%%%!"
  8. :loop
  9. if defined str set/a n+=1&set "str=!str:~1!"&goto loop
  10. echo %n%
  11. pause>nul
复制代码
shqf的方法高明,放于自身批处理中。

[ 本帖最后由 pusofalse 于 2008-8-16 08:01 编辑 ]
作者: terse    时间: 2008-8-16 12:15

少个出错几率
  1. @echo off
  2. rem &<>%%a%%!ver!&^^^ ^*~                     are you o                 k ?" : \  / ` `  verfdxcweippo opj x ds gw !%%
  3. for /f "skip=1 delims=" %%i in (%~0) do set "str=%%i"&goto lp
  4. :lp
  5.     setlocal enabledelayedexpansion
  6.     set str=!str!
  7.     for /l %%i in (1,1,255) do if "!str:~%%i,1!"=="" set/a n=%%i-4&echo !n!&pause
复制代码

作者: 523066680    时间: 2008-8-17 08:07

我觉得上面的方法高明~!不过我通过在命令行输入 yourbat.bat
才执行成功……
稍微改了一下……
@echo off
rem &<>%%a%%!ver!&^^^ ^*~                     are you o                 k ?" : \  / ` `  verfdxcweippo opj x ds gw !%%
for /f "skip=1 delims=" %%i in ('type %0') do set "str=%%i"&goto lp
:lp
    setlocal enabledelayedexpansion
    set str=!str!
    for /l %%i in (1,1,255) do if "!str:~%%i!"=="" set/a n=%%i-4&echo !n!&pause



-------------------------我又试了一下-----------------------------
  1. @echo off
  2. ::&<>%%a%%!ver!&^^^ ^*~                     are you o                 k ?" : \  / ` `  verfdxcweippo opj x ds gw !%%
  3. for /f "skip=1 delims=" %%i in ('type %0') do set "str=%%i"&goto lp
  4. :lp
  5.     setlocal enabledelayedexpansion
  6.     for /l %%i in (1,1,255) do if "!str:~%%i!"=="" set/a n=%%i-2&echo !n!&pause&exit
复制代码
少了一句set str=!str!但执行结果一样
在前面的代码中,这一句是否起着一些作用

[ 本帖最后由 523066680 于 2009-1-31 14:04 编辑 ]
作者: terse    时间: 2008-8-18 01:42

原帖由 523066680 于 2008-8-17 08:07 发表
我觉得上面的方法高明~!不过我通过在命令行输入 yourbat.bat
才执行成功……
稍微改了一下……
@echo off
rem &%%a%%!ver!&^^^ ^*~                     are you o                 k ?" : \  / ` `  verfdxcwe ...

确实应该 type %0   因为文件名空格问题  谢523066680兄的细心
set str=!str! 多余
我在前面就已经粗心了   开始我以为是前面是计算整个一排的 所以我改一下的
现在看前面::等同REM   如是这样  set /p str=<%0  也一样
作者: 523066680    时间: 2008-8-18 17:57

习题1.1我才搞出一个偏方,哈哈,大家看下 (貌似有些吃力不讨好)
@echo off
setlocal enabledelayedexpansion
set no1=i like the bathome,because here is the batch of the world.
set code=a1a2a3a4a5a6a7a8a9101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
set code2=abababababababababababababababababababababababababababababababababababababababab
    set no2=%no1%%code2%
    set no3=%no1%%code%
    set no2=%no2:~0,80%
    set no3=%no3:~0,80%
    if "%no2:~-1%"=="a" (
      set n=%no3:~-3,2% &set n=!n:a=!
      set /a no4=80-!n!*2-1
      echo !no4!
      ) else (
        set n=%no3:~-2% &set n=!n:a=!
        set /a no4=80-!n!*2
        echo !no4!
        )
pause
作者: Batcher    时间: 2008-8-18 19:21     标题: 回复 22楼 的帖子

这样是不是简单些?
  1. @echo off
  2. set str=i like the bathome,because here is the batch of the world.
  3. set length=0
  4. setlocal enabledelayedexpansion
  5. for /l %%a in (0,1,80) do (
  6.   if "!str:~%%a,1!" neq "" (
  7.     set /a length+=1
  8.   ) else (
  9.     goto :show
  10.   )
  11. )
  12. goto :eof
  13. :show
  14. echo !length!
复制代码

作者: 523066680    时间: 2008-8-18 20:39

哈哈 我说了是偏方嘛  就是搞个思路而已。


22楼的代码虽长,但只用9次set命令(前面7次,if选择其中一个-两次) 上面set很长的变量也是为了铺垫

如果要短,那当然还是其他代码啦,
像 楼上大家做习题1.2的代码就非常短而精悍。

[ 本帖最后由 523066680 于 2008-8-19 08:01 编辑 ]
作者: 523066680    时间: 2008-8-19 07:52

哈哈,改进一下,大家看
@echo off
set no1=i like the bathome,because here is the batch of the world.
set code1=%no1%1010101010101010101010101010101010101010101010101010101010101010101010101010101010
set code2=%no1%a1a2a3a4a5a6a7a8a91011121314151617181920212223242526272829303132333435363738394041
    set no2=%code2:~0,82%
    call,set /a num=-%code1:~81,1%-2
    call,set num=%%no2:~%num%,2%%
set /a n=82-%num:a=%*2-%code1:~81,1%
echo %n%
pause
使用了7句set,可测量最大为80个字符,不包括中文,特殊字符……

[ 本帖最后由 523066680 于 2008-8-19 08:19 编辑 ]
作者: 523066680    时间: 2009-1-31 13:14

defanve发起项目  关系到字符串处理  俺又回到这个帖子
还有余兴 继续讨论。 (不禁难过 我22楼的东西咋这么粗糙~ 哎 )

    应该说terse19楼的代码是各答案中比较完善的一个。
咱现在要想办法把它升级一下。
    1.找漏洞,当字符串最后一个是 ^ 符号的时候 导致分行语句连接
执行错误,这是个麻烦事儿。
    2.局限, skip=1 ::字符串必须放在第二行。
    3.升级  字符串个数不限

处理中……

[ 本帖最后由 523066680 于 2009-1-31 13:22 编辑 ]
作者: defanive    时间: 2009-1-31 13:20

作为一个随时调用的函数,你不可能修改批处理,这样实在无爱。。。

还是要作为传值参数一样,call的时候给值,然后标签里%1使用。。。

另外,我那个函数应该是可以的,你再看看:

@echo off
setlocal enabledelayedexpansion
:loop
set /p a=Type :
call :StrLen "vl" "%a%"
echo Length : %vl%
pause>nul
goto loop
:StrLen
setlocal enableextensions
set "str=a%~2"
set "str=%str:"=s%"
set "str=%str:^^=s%"
set "str=!str:%%=s!"
set /a strlength=0
:StrLen_1
set /a strlength+=1
if not "!str:~%strlength%,1!"=="" goto StrLen_1
endlocal&set /a "%~1=%strlength%-1"
goto :EOF
作者: 523066680    时间: 2009-1-31 14:34

对%的麻烦感到如此无奈 ~  我们老是对自己的代码提出要求
由于批处理本身的限制 咱是不是也对使用者提提要求?

例如
1.如果遇到敏感字符 请用别的字符代替~(咔咔   我怎么能这样想呢? 无奈~)
作者: defanive    时间: 2009-1-31 16:13

我的代码测试成功灭?

没什么要拓展的就入库了?
作者: terse    时间: 2009-1-31 16:35

直接点的怎么样呢
  1. @echo off&setlocal enabledelayedexpansion
  2. set/p str=Type :
  3. for /l %%i in (1,1,10000) do if "!str:~%%i,1!"=="" echo %%i&pause&exit
复制代码

作者: defanive    时间: 2009-1-31 17:23

  1. :StrLen
  2. setlocal enableextensions
  3. set "str=a%~2"
  4. set "str=%str:"=s%"
  5. set "str=%str:^^=s%"
  6. set "str=!str:%%=s!"
  7. set /a strlength=0
  8. :StrLen_1
  9. set /a strlength+=1
  10. if not "!str:~%strlength%,1!"=="" goto StrLen_1
  11. endlocal&set /a "%~1=%strlength%-1"
  12. goto :EOF
复制代码


如果作为库函数的话,我觉得LS的代码不行,因为你不知道变量可能的长度,就把for设定在10000了,缺乏通用性

如果要完全通用的话,就要把10000改成2^31-1,就是2147483647

改完之后,执行时间就增长了。。。
作者: terse    时间: 2009-1-31 18:54

RE:  defanive兄
我前面这样处理 是因为 变量的的长度是有限制的  这个以前有讨论
执行时间  视变量长度  不是一直循环的 空值就退出啊
下面的代码  前面贴有的  我只是简化下  应该也可判断
  1. @echo off&setlocal enabledelayedexpansion
  2. set/p str=Type :
  3. :lp
  4. if defined str (
  5.     set/a n+=1
  6.     set str=!str:~1!
  7.     goto lp
  8. )
  9. echo %n%
  10. pause
复制代码

作者: terse    时间: 2009-1-31 19:14

27楼代码 是否可简化下?
  1. @echo off&setlocal enabledelayedexpansion
  2. set/p str=Type :
  3. :lp
  4. if not "!str:~%n%,1!"=="" set /a n+=1&goto lp
  5. echo;%n%
  6. pause
复制代码

作者: defanive    时间: 2009-1-31 19:20

:StrLen
setlocal enableextensions
set "str=%~2"
:StrLen_1
if defined str (
        set/a n+=1
        set "str=%str:~1%"
        goto StrLen_1
)
endlocal&set "%~1=%n%"
goto :EOF

函数整理成这样了,同意么?
作者: 523066680    时间: 2009-1-31 19:42     标题: 回复 33楼 的帖子

defan是想用函数的形式做这个东西

标签是 :StrLen
用类似 call :StrLen "var" "字符串" 的形式调用
var是用来返回 字符串长度 的变量名

我小改一下就又出现麻烦了 还请 terse 指教一二。
作者: taojunyi    时间: 2009-2-9 22:55

1-1
  1. @echo off
  2. set "a= i like the bathome,because here is the batch of the world."
  3. set /a num=0
  4. :loop
  5. set /a num+=1
  6. set a=%a:~1%
  7. if "%a%"=="" (goto :ne1) else goto :loop
  8. :ne1
  9. echo %num%
  10. pause
复制代码

作者: Batcher    时间: 2009-2-9 23:24     标题: 回复 34楼 的帖子

不能支持特殊字符的话,叫做函数是否不太好呢?
作者: qjfke    时间: 2009-4-14 17:26

看不懂哦,那个什么~:什么什么的,在那有详细的介绍。先谢谢了
作者: Batcher    时间: 2009-4-14 18:18     标题: 回复 38楼 的帖子

本论坛教学区搜索“set”
作者: keen    时间: 2009-4-14 19:42

原帖由 Batcher 于 2008-8-15 08:39 发表
1.1@echo off
set str=i like the bathome,because here is the batch of the world.
for /f "skip=1 delims=:" %%a in ('^(echo "%str%"^&echo.^)^|findstr /o ".*"') do set /a length=%%a-5
echo %length%


我不是很明白 set /a length=%%a-5,为什么减5,我见过减2的。能给解释一下吗?
作者: Batcher    时间: 2009-4-14 22:27     标题: 回复 40楼 的帖子

你能先解释一下为什么减2吗?
然后我再说说减5的原因。
作者: keen    时间: 2009-4-16 14:52     标题: 回复 41楼 的帖子

减2,是因为减去回车和换行
作者: Batcher    时间: 2009-4-16 15:07     标题: 回复 42楼 的帖子

开始
运行
cmd
分别运行下面两个命令
(echo "bathome"&echo.)|findstr /o ".*"
(echo bathome&echo.)|findstr /o ".*"
思考一下为什么减5?思考一下为什么减2是错的?
作者: keen    时间: 2009-4-18 23:00     标题: 回复 43楼 的帖子

我的意思不是说在这道题中减2,我只是在别的代码中见过减2的,这里减5是对的,我只是很不明白这个原理。

我把你说的这两个代码实验了
(echo "bathome"&echo.)|findstr /o ".*"
(echo bathome&echo.)|findstr /o ".*"
实验结果是:
0:"bathome"
12:

0:bathome
10:

我还是没明白什么原理。我只是发现你给的两种代码因为有 ""  号,而两个值不同了。
作者: Batcher    时间: 2009-4-18 23:15     标题: 回复 44楼 的帖子

能把你看到的减2的代码贴出来看看么,最好能够注明出处?然后我告诉你我的代码中减5的原理。
作者: keen    时间: 2009-4-19 22:21     标题: 回复 45楼 的帖子

我找了一下,原来是新手区的  [ 新手练习 4 ] 批处理计算字符串长度

http://www.bathome.net/viewthrea ... A4%B6%C8&page=1

其中4楼的代码中的法四:
  1. rem ----------[法四]主程序开始---------------------
  2. echo %var%>a.txt
  3. echo.>>a.txt
  4. for /f "tokens=1 delims=:" %%i in ('findstr /o .* a.txt') do set /a length=%%i-2&if not %%i  
  5. equ 0 echo 共有%length%个字符&goto end
  6. :end
  7. del a.txt
  8. rem ----------[法四]主程序结束---------------------
复制代码
这段代码中就是用减2。

而且你在14楼说是减2就是减去回车和换行。
作者: Batcher    时间: 2009-4-19 22:51     标题: 回复 46楼 的帖子

那个是通过判断文件大小来计算字符串长度的,跟你在40楼提出的问题略有不同。我们还是以你40楼的问题来讨论一下吧。

(echo "bathome"&echo.)|findstr /o ".*"的结果你已经看到了,就是:

0:"bathome"
12:

这个命令用在for里面,得到的效果就是set /a length=12-5,为什么减去5呢?

findstr /o计算的是偏移量,偏移量从零开始,一对双引号+字符串bathome这7个字母+回车+换行,总共11个,下一个偏移量自然是12,因此要想用这个方法得到字符串bathome的长度就需要减去5。

--------------------------------------------

以上为错误言论,请忽略。解释见49楼。


[ 本帖最后由 Batcher 于 2009-4-20 19:17 编辑 ]
作者: keen    时间: 2009-4-20 00:14     标题: 回复 47楼 的帖子

非常感谢batcher,这么有耐心回答我的疑问,但是我还是没明白它跟输入到文件,再读出来的时候,为什么不一样?
作者: everest79    时间: 2009-4-20 19:22

直接输出在con设备上,会有一个控制字符,所以要减3,而在文件中,只有cf跟lf,减2就可以了
作者: Batcher    时间: 2009-4-20 19:29     标题: 回复 48楼 的帖子

当我们把字符串重定向输出到文件中再计算偏移量的情况,比较好理解,多出来的两个字节就是行尾的回车和换行。

当我们直接在for命令中获取字符串偏移量时,情况会变得稍微复杂。请把一下代码保存为test.bat,然后运行。
  1. (echo BatHome&echo.)|findstr /o ".*"
  2. pause
复制代码
结果如下:
C:\Test>(echo BatHome  & echo.)  | findstr /o ".*"
0:BatHome
10:

请注意,实际运行时,命令行解释器在&符号前面添加了两个空格(通常情况下,命令分隔符是一个空格),这多出来的一个空格就导致了偏移量增加了一个,这就是我们在计算字符串BatHome长度的时候需要减去3的原因。
作者: lxzzr    时间: 2009-4-23 01:11

  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. set /p a=请输入要计算长度的字符串:
  4. for /l %%a in (1,1,1000000) do (
  5. set k=!a:~%%a,1!
  6. if not defined k (
  7. echo 字符串长度:%%a
  8. pause>nul
  9. exit
  10. )
  11. )
复制代码

[ 本帖最后由 lxzzr 于 2009-4-23 03:13 编辑 ]
作者: netbenton    时间: 2009-4-29 11:54

楼上的,等半天都算不出来,
其实set /p输入的行最大为1024字符,变量长度也只有8189 个字符,没必要1000000,

for /l 在预处理时会首先按数分配完后才一条条执行的,分配时也是要时间的,大概是80次等一个set a=a的执行时间。
作者: everest79    时间: 2009-4-30 22:04

原帖由 Batcher 于 2009-4-20 19:29 发表
当我们把字符串重定向输出到文件中再计算偏移量的情况,比较好理解,多出来的两个字节就是行尾的回车和换行。

当我们直接在for命令中获取字符串偏移量时,情况会变得稍微复杂。请把一下代码保存为test.bat,然后运 ...


cmd下输入echo a            >1.txt
打开1.txt,ctrl+A
cmd下输入echo a>2.txt
打开2.txt,ctrl+A

同理
(echo bathome&echo.)>1.txt



(echo.&echo.&echo.)|findstr /o .*
这个多出来的字符不是空格,是一个控制符,推测是行输出的eof标志
作者: Batcher    时间: 2009-4-30 22:46     标题: 回复 53楼 的帖子

行结束符应该是eol而不是eof吧?
不过这个推测似乎缺乏证据的支持。
作者: everest79    时间: 2009-4-30 23:27

原帖由 Batcher 于 2009-4-30 22:46 发表
行结束符应该是eol而不是eof吧?
不过这个推测似乎缺乏证据的支持。


确定不知道具体是啥,嘿嘿
我刚发现这个时也有过讨论,记得有人分析过

(echo.abc&echo.) >1.txt
不带空格
(echo.abc&echo.)|more >2.txt
带上了空格

(dir /b ?.txt&echo.&echo.)|findstr /o .*
显示的结果为
0:1.txt
7:2.txt //+2
14: //+2
17: //这里是多3
最后假设多出来的一个字符是echo的特殊控制符,在con设备上被忽略,但通过管道符就成了可见,在debug下查看就显示为20
作者: netbenton    时间: 2009-4-30 23:49

同意楼上的观点,命令行与参数是会有一个空格分开的,并不是连在一起的。
作者: Batcher    时间: 2009-5-5 13:34     标题: 回复 55楼 的帖子

  1. (echo TestStr&echo.)|findstr /o ".*">a.txt
复制代码
我们把结果输出到文件里面,可以清楚的看到行尾多出来的那个字符就是一个空格(十六进制编辑器下显示为20)。

[ 本帖最后由 Batcher 于 2009-5-5 13:36 编辑 ]
作者: keen    时间: 2009-5-11 22:54     标题: 回复 3楼 的帖子

可以不用第三行代码
  1. for /f "tokens=*" %%a in ('dir x.x /-c ^|find " 字节" ^|find /v ":"') do (
复制代码
中的
  1. ^|find /v ":"
复制代码


不知道这句有什么作用?

修改楼主代码:
  1. @echo off
  2. echo i like the bathome,because here is the batch of the world.>x.x
  3. for /f "tokens=*" %%i in ('dir x.x /-c^|find " 字节"') do (
  4.     for /f "tokens=3" %%j in ('echo %%i') do (
  5.         set /a len=%%j-2&call,echo %%len%%&del x.x /q
  6. ))&pause
复制代码


请指正!

[ 本帖最后由 keen 于 2009-5-11 23:11 编辑 ]
作者: keen    时间: 2009-5-11 23:01

1.1
既然楼主说没有超过80个字符,所以:
  1. @echo off
  2. set "str=i like the bathome,because here is the batch of the world."
  3. for /l %%i in (0 1 80) do (
  4.     call,set var=%%str:~%%i,1%%
  5.     if not defined var set n=%%i&goto end
  6. )
  7. :end
  8. echo %n%&pause
复制代码

[ 本帖最后由 keen 于 2009-5-11 23:40 编辑 ]
作者: netbenton    时间: 2009-5-11 23:18     标题: re 58,59楼

写到临时文件的话,这样就可以了,dir + find 效率太低了
  1. @echo off
  2. echo i like the bathome,because here is the batch of the world.>x.x
  3. for %%a in (x.x) do set/a n=%%~za-2
  4. echo %n%
  5. pause
复制代码
80字符以内可以这样,是否更好一点呢?
  1. @echo off&setlocal enabledelayedexpansion
  2. set "str=i like the bathome,because here is the batch of the world."
  3. for /l %%i in (0 1 80) do (if "!str:~%%i,1!" equ "" set n=%%i&goto end)
  4. set n=0
  5. :end
  6. echo %n%&pause
复制代码

[ 本帖最后由 netbenton 于 2009-5-11 23:31 编辑 ]
作者: Batcher    时间: 2009-5-11 23:24     标题: 回复 60楼 的帖子

你决定这个能得到正确结果?
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Test>type test.bat
@echo off
echo BatHome>x.x
for %%a in (x.x) do echo %%~za

C:\Test>test.bat
9

作者: netbenton    时间: 2009-5-11 23:27     标题: re 61楼

多了两个吧,是回车和换行符,减2就可以了
作者: keen    时间: 2009-5-11 23:37     标题: 回复 60楼 的帖子

58楼的代码是修正楼主3楼的代码,不是我自己写的。

59楼的代码,你说的对,我多用了一个 set /a n+=1 做计数器,多此一举了。谢谢指正,在59楼修正。
作者: zgq0301    时间: 2009-11-13 21:59

  1. rem 1.1 1.2字符串长度不限,可含特殊字符。
  2. @echo off &setlocal enabledelayedexpansion
  3. set /p str=Please input string:&set a=&set /a var=0
  4. :loop
  5.     set a=!str:~%var%,1!
  6.     set /a err=%errorlevel%
  7.     if !err! equ 0 (set /a var+=1&goto :loop )
  8.     set /a var-=1
  9. echo the length of string is:%var%
  10. pause>nul
复制代码

[ 本帖最后由 zgq0301 于 2009-11-14 09:07 编辑 ]
作者: Taurus    时间: 2009-11-14 17:41

原帖由 netbenton 于 2009-4-29 11:54 发表
楼上的,等半天都算不出来,
其实set /p输入的行最大为1024字符,变量长度也只有8189 个字符,没必要1000000,

for /l 在预处理时会首先按数分配完后才一条条执行的,分配时也是要时间的,大概是80次等一个set a ...

1024?
奇怪了...为何我输入的最大数为1021的?

我是在下面试验得到1021这数字的,是那里的分别影响了结果?
望指教
@echo off
set/p str=
:lp
if defined str set str=%str:~1%&set/a l+=1&goto lp
echo %l%
pause>nul

[ 本帖最后由 Taurus 于 2009-11-14 17:44 编辑 ]
作者: neorobin    时间: 2009-12-11 18:23     标题: 二分搜索算法

http://www.bathome.net/viewthrea ... amp;page=1#pid43293
作者: 491321720xxw    时间: 2010-10-2 23:11

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set /p a=请输入一窜字符串:
  4. set m=0
  5. :xxw
  6. if not "!a:~%m%,1!"==""  set /a m=!m!+1&goto :xxw
  7. echo 有%m%个字符!!!!!!!!
  8. pause&goto :eof
复制代码

作者: Hello123World    时间: 2011-8-3 15:00

第一题不计算空格数:
  1. @echo off&SetLocal EnableDelayedExpansion
  2. Set str=i like the bathome,because here is the batch of the world.
  3. Set n=0
  4. Set str=%str: =%
  5. Set a=
  6. :loop
  7. Set a=!str:~%n%,1!
  8. if not "%a%"=="" (Set /a n+=1 & goto loop
  9. ) Else (echo !n!)
  10. pause>nul
复制代码

作者: Hello123World    时间: 2011-8-3 15:14

回复 3# 523066680
为什么要在原字节大小上减去2?难道默认字符还要多占去2个字节?
作者: CrLf    时间: 2011-8-3 18:09

回复 69# Hello123World


    因为回车换行占两个字符
作者: CrLf    时间: 2011-8-3 18:31

  1. (echo TestStr&echo.)|findstr /o ".*">a.txt
复制代码
打开回显,一目了然。这句中之所以多出来一个空格,原因是预处理时语句被重组成“规范”的格式:
  1. (echo TestStr  & echo.)  | findstr /o ".*"
复制代码
做了如下一组实验:
  1. rem>nul 3>test.txt
  2. echo TestStr
  3. echo TestStr&echo.
  4. (echo TestStr&echo.)
  5. (echo TestStr&echo.)|findstr /o ".*"
  6. test.txt
复制代码
可见 echo TestStr 时,cmd 为其后缀一个仅在预处理中有效的空格,而 & 号又为自身前后添加一个空格。当管道中出现语块或者存在内部命令时,管道前的内容将作为参数交给新的 cmd 进程,此时原本只存在于预处理中的空格也许因为被新的 cmd 进程误认为是 echo 命令的参数而非分隔符显示出来。
作者: Hello123World    时间: 2011-8-4 12:21

回复 70# CrLf
可是那个字符串哪里回车换行了,哦,预处理默认echo后回车换行。
作者: qixiaobin0715    时间: 2021-4-18 15:32

这一道题目牵出很多故事,太精彩了,真是受益匪浅。
作者: qixiaobin0715    时间: 2021-4-18 15:39

习题1.2中,如果字符串中加一个单%,有些代码就可能失效。
作者: lengmoke    时间: 2021-9-24 16:47

  1. :%%a%%!ver!&^^^ ^*~                     are you o                 k ?" : \  / ` `  verfdxcweippo opj x ds gw !%%
  2. ::将字符串放于第一行,并加上:
  3. @echo off & setlocal EnableDelayedExpansion
  4. set /p str=<%0
  5. :count
  6. set str=!str:~1!
  7. if defined str ( set /a n+=1 & goto :count )
  8. echo %n%
复制代码





欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2