中国DOS联盟论坛

China DOS Union

-- Unite DOS · Advance DOS · Grow DOS --
Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum
Guest | Log in | Register | Members | Search | China DOS Union
中国DOS联盟论坛
The time now is 2026-08-29 08:05
47,816 topics / 349,916 posts / today 0 new / 48,265 members
DOS批处理 & 脚本技术(批处理室) » [Discussion][NT]Batch code to check the length of a string for errors
Printable Version  3,473 / 9
Floor1 3742668 Posted 2006-03-30 12:07
荣誉版主 Posts 718 Credits 2,013
### Problem analysis
1. **Vulnerability analysis**:
- **Edge case handling**:
- When the input string is an empty string, the current code will have problems. For example, if `mystr` is an empty string, the `bflen` function will calculate incorrectly. Because when `str` is an empty string, the loop in the `len` label will still execute, and finally `ret` will be calculated incorrectly.
- **Variable scope issues**:
- The variables `num`, `str`, and `ret` are set in the `bflen` function. If there are other parts of the code that also use these variable names, there may be variable name conflict problems.

### Optimization suggestions
1. **Handle empty string situation**:
in the `bflen` function, add a judgment at the beginning of the `bflen` function to handle the case of an empty string. For example:
```batch
:bflen
set num=
set str=
set ret=
if "%~1"=="" (
set ret=0
goto :eof
)
set str=%1
:len
set str=%str:~0,-1%
set /a num = %num% + 1
if defined str goto len
set /a ret = %num% - 2
set num=
goto :eof
```
2. **Improve variable scope**:
- To avoid variable name conflicts, you can use more specific variable names. For example, prefix the variable names in the `bflen` function with `bflen_`. Modify the relevant parts as follows:
```batch
:bflen
set bflen_num=
set bflen_str=
set bflen_ret=
if "%~1"=="" (
set bflen_ret=0
goto :eof
)
set bflen_str=%1
:len
set bflen_str=%bflen_str:~0,-1%
set /a bflen_num = %bflen_num% + 1
if defined bflen_str goto len
set /a bflen_ret = %bflen_num% - 2
set bflen_num=
set ret=%bflen_ret%
goto :eof
```

The above code first handles the situation of an empty string and then improves the variable scope to make the code more robust.

```code
@echo off
:began
set /p mystr=输入要计算长度的字符串:
echo %mystr:~0,1% | findstr /i "q" 1>nul 2>nul && exit rem 输入q退出

call :bflen "%mystr%" rem 这两句调用bflen,返回长度到变量ret中。
echo 字符串: "%mystr%"
echo 长 度: %ret%

goto began

:bflen
set bflen_num=
set bflen_str=
set bflen_ret=
if "%~1"=="" (
set bflen_ret=0
goto :eof
)
set bflen_str=%1
:len
set bflen_str=%bflen_str:~0,-1%
set /a bflen_num = %bflen_num% + 1
if defined bflen_str goto len
set /a bflen_ret = %bflen_num% - 2
set bflen_num=
set ret=%bflen_ret%
goto :eof
```
Floor2 willsort Posted 2006-03-30 15:24
元老会员 Posts 1,512 Credits 4,432
Re 3742668:

There are some flaws in the program's exit statement, which will cause all strings starting with q to not be able to measure the length. In addition, it feels that the algorithm for getting the string length is somewhat inefficient. Originally, the algorithm of echoing the string to a file and then getting the file length was used . But it also has compatibility problems of not being able to measure the length of some special strings, so it was changed to the current algorithm .

Test cases:
command
command>nul
"command>nul"
command"com



Floor3 3742668 Posted 2006-03-30 16:44
荣誉版主 Posts 718 Credits 2,013
Thanks in advance.
But maybe I didn't make it clear. My original intention was to make the part of getting the string length into something like a function, so that it can be directly copied and called in other batch scripts. Hehe, it's easier to be lazy when there are more accumulations.
If I write another batch script now, I can directly copy the statements after the bflen label and call them using call.
Floor4 yardian Posted 2006-12-17 05:53
中级用户 Posts 85 Credits 305
The code 2 on the second floor has to calculate 1000 times each time, which is too slow.
Floor5 namejm Posted 2006-12-17 07:29
荣誉版主 Posts 1,737 Credits 5,226 From 成都
It won't. It will just jump out after executing the number of times equal to the length of the string. Please pay attention to the line && goto :_endfor.
Floor6 zzs162 Posted 2007-02-18 20:30
初级用户 Posts 11 Credits 27
Floor7 skyearth Posted 2007-03-02 00:35
初级用户 Posts 13 Credits 34
There is also a problem with code 2. If Chinese is included, it is only regarded as 1 byte
Floor8 slore Posted 2007-03-02 00:40
铂金会员 Posts 2,478 Credits 5,212
Originally posted by skyearth at 2007-3-1 11:35:
There is also a problem with code 2. If Chinese is included, it is only regarded as 1 byte.


This is simply about the number of bits.

It's convenient for VBS to directly use len(str)...
Floor9 slore Posted 2007-03-02 00:43
铂金会员 Posts 2,478 Credits 5,212
The biggest bug is that it can only be single-line.
Floor10 skyearth Posted 2007-03-03 03:20
初级用户 Posts 13 Credits 34
Maybe not described clearly. I want to judge how to get the actual number of bytes when mixing Chinese and English characters with BAT. For example, "这是一个test", if using code one, the result 12 is the correct result, while code two has a result of 8, which is inconsistent with the actual number of bytes, this is just the number of characters.

I am making a script that can display progress information in place. Because the length of Chinese characters cannot be calculated correctly, the length of backspace is not easy to control, please understand.
[ Contact the Union admin team - 中国DOS联盟 - Standard version ]
Sponsored by ifanr Inc | © 2001–2023