[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] 批处理查找出/获取txt文本中字符个数最多的行/字符串长度最长的行

本帖最后由 pcl_test 于 2016-9-9 22:47 编辑
  1. @echo off
  2. Setlocal Enabledelayedexpansion
  3. set n=0
  4. for /f "delims=" %%i in (a.txt) do (
  5. set "ke=%%i"
  6. set ke1=!ke: =!
  7. set m=0
  8. call :1
  9. call echo %%ke1%%
  10. )
  11. echo %wang%
  12. pause
  13. goto :eof
  14. :1
  15. if not "!ke1:~%m%,1!"=="" set /a m+=1&goto 1
  16. if %m% gtr %n% set n=%m%&set wang=%ke%
  17. echo %m%
  18. goto :eof
复制代码
以上是浅默写的,也算是比较适合我这类新手更容易看懂的代码,在我自己写以及查看高手门代码的时候,遇到了很多不懂,也小有心得体会,所以我就发了这个帖子询问,因为论坛发贴规则,题目我就这样写了,也算是一个笔记吧
先写关于这个代码的我懂的:
  1. for /f "delims=" %%i in (a.txt) do (
  2. set "ke=%%i"
  3. set ke1=!ke: =!
复制代码
这基本上可以算是一个替换字符的模本,看看这一句set %%i=!%%i: =!,echo %%i,会发现set完全没有作用。也就是说%%i这样的变量是不能直接进行字符串替换的,当然,也可以set ke=!ke: =!。ke只是一个名字而已,可以用其他字符替换,不过最好是有意义的,并且看的懂的。这里为什么是ke1而不是ke?下面再解释。
set m=0

if not "!ke1:~%m%,1!"=="" set /a m+=1&goto 1
这两句一定要放在一起来说,这两句代码是最简单的求字符串长度代码,原理后面会提到。如果只是求1段字符串长度的话,其实后面一句就可以了,只不过在这个程序里,他是要对每一行分别计算长度,有很多个不同的值,为什么要定义m=0?因为我们在计算第一行字符串长度后,需要把变量m初始化为0,才能正确的计算下面每行的长度,如果不初始化,那么在计算完第一行后,m将会被定义数x,如果第2行的字符串长度没有第一行多,而且如果字符数不为0的话,那么他就会简单的把x这个值赋予第2行的字符串长度m,但实际上没那么多。如果第3行比第1行多,那么第3行将能正确的取得,但是第4行如果又少了的话,那么第4行将会取得上1个循环的数,也就是第3行的数,以此类推。而且这个set m=0的位置非常讲究,如果放在for循环前,结果将会跟没定义一样,为什么?因为这个计算只是在循环内部计算,外部定义对内部没有起到作用,如果放在子代码段开头呢?将会发现程序进入了死循环,因为这段对每一行字符串长度进行计算的时候,他是先去掉第一个字符,如果剩下的字符不为空的话,m自加1为1,然后再计算剩下的字符,如果还不为空,那么m自加1为2,以此类推。如果你在子代码段开头设置set n=0,将会使m=0,而不是1,然后再进行计算,这样他永远就无法计算出来,从第一行开始就进入死循环。

set n=0     

if %m% gtr %n% set n=%m%&set wang=%ke%

set ke1=!ke: =!
这里用set ke1=!ke: =!是因为题目要求,如果我们用set ke=!ke: =!的话,在代码执行到最后,ke的值是一行没有空格的字符串,我们输出(echo %wang%)时,得到的也就是一串没有空格的字符串,但是这里为什么会在程度段开头就设置n=0,并且在子代码段里对n跟m进行比较,并赋值呢?看代码的意思:如果字符串长度比n大,那么n就等于字符串长度,关键在于set wang=%ke%是怎样把字符串最长的行(带空格)赋予wang的呢?再来观察整个程序,就会小有发现,如果第1行的字符串长度比0大,那么wang就等于第1行字符串,如果后面的行都没有n(这里是第1行的的字符串长度)大,那么就不会对n进行再赋值,wang就没有变化。。。但是如果后面的值有比前面的大,那么就重新进行赋值,最后就能得出正确的结果

关键是最后的代码,想了我2天,才想明白,所以就发来,希望有不明白的可以看到,明白的就飘过算了,如有不对请指点指点。就像老师教编程的时候一样,说程序本身并不重要,重要的是思想

[ 本帖最后由 sgaizxt001 于 2010-2-6 04:14 编辑 ]
1

评分人数

    • batman: 学习精神难能可贵PB + 5

&&既然楼主如此求真,那么我就索性再给出一种方法并加以简单说明,借用原练习的文本a.txt如下:
  1. aaaaaaa                                 aaaa bbbbbb ccccccccccc dddd
  2. aa  aaaaaaa bbbbbbbb cccccccccc ddddddddddddd eeeeeee
  3.      aaaaaaaaaaaa bbbbbbbbbbb cccccccccccccccccccc
  4. aaaaaaaaa        ccccccccc bbbbbbbbbbbbb               ddddddddddddddddd
  5.                 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aa
  6.                     aaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbb
复制代码
现在我们来找出其中字符数最多的行(含空格),代码如下:
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a max=0
  3. for /f "tokens=1,2 delims=:" %%a in ('"(type a.txt&echo.)"^|findstr /o .*') do (
  4.     set /a b=%%a
  5.     if "!a!" neq "" (
  6.        set /a a=b-a-2
  7.        if !a! geq !max! set /a max=a&set "_!max!=!str!"
  8.     )
  9.     set /a a=%%a&set "str=%%b"
  10. )
  11. echo 字符数最多的行为!_%max%!,字符数有%max%个
  12. pause>nul
复制代码
  1. 说明:
  2.     首选我们来说下findstr /o,这是个打印字符偏移量的命令,而所谓偏移就肯定有原始点,那么这个原始点是不
  3. 是每行的开头(最左端)呢?不是,这个原点是文档的最左上角。而偏移量是指的光标距这个原点的运行距离,所以不
  4. 总是指的直线距离,并且是累加的。而文本每行的结束都有两个不可见字符回车和换行符,因此每换一行字符偏移
  5. 量要加上2,在这里还要说明下文本每多一个半角字符偏移量+1,多一个全角字符偏移量+2,而我们的a.txt中只有半
  6. 角字符,所以字符数和偏移量完全可以对应起来,而findstr /o计算出的偏移量均表示的是行首距原点的偏移量,因
  7. 此用下行行首的偏移量减去上行行首偏移量就能得出上行的字符数。但这里又出来一个问题,最后一行怎么办?因
  8. 此在代码中用type a.txt&echo.为输出多加了一个空行,再将输出结果进行findstr /o .*,这样就能计算出末行的字符
  9. 数了。至于怎么判断哪一行的字符数最多并赋值输出的过程,我想楼主应该明白,在这里就不再说明了。如果文本
  10. 中既有半角字符又有全角字符,那么本人推荐使用随风版主的折半法来计算每行的字符数。
复制代码

[ 本帖最后由 batman 于 2010-2-6 12:23 编辑 ]
***共同提高***

TOP

返回列表