|
无奈何
荣誉版主
      
积分 1338
发帖 356
注册 2005-7-15
状态 离线
|
   『楼 主』:
[原创]批处理参数问题一点谈
使用 LLM 解释/回答一下
批处理参数问题一点谈
最近编写了一个批处理程序,想让程序能够灵活的接收两个以下的参数,但在完成过程中几经卡壳,比如怎么解决数量不等的参数个数,怎么实现参数类型的判断。经过一段时间的思考和摸索,总算比较满意的解决了这些问题。接下来我谈谈这个过程,如果你想测试效果的话请在 NT 系统下进行。
先交待一下这个批处理程序想要接收的参数,一个参数为路径,另一个参数为数字。这样便有了下面的几种组合变换:
1、空
2、路径
3、数字
4、路径 + 数字
5、数字 + 路径
6、路径 + 路径
7、数字 + 数字
前五种情况是程序需要处理的正常的参数组合,后两种是不期望的组合。先看下面一段演示程序,一起来探讨这个过程的处理与实现。
:: demo.cmd 批处理参数处理演示 2000、XP ↑
:: by:无奈何 email:wunaihe@gmail.com 2005.11.17
1│@echo off
2│setlocal
3│set "p1=%~1"
4│set "p2=%~2"
5│set flag_d=0
6│set flag_n=0
7│if not defined p2 (
8│ if not defined p1 (
9│ set "directory=."
10│ ) else (
11│ set "directory=."
12│ call :_test "%p1%"
13│ )
14│) else (
15│ call :_test "%p1%"
16│ call :_test "%p2%"
17│ )
18│if %flag_n% == 2 echo 参数为两个数字 &goto :EOF
19│if %flag_d% == 2 echo 参数为两个目录 &goto :EOF
20│echo 目录为:%directory% 数字为:%number%
21│goto :EOF
22│
23│:_test
24│set "x=%~1"
25│set /a "y=x+1-1"
26│if "%y%" == "%x%" (
27│ set "number=%x%"
28│ set /a flag_n+=1
29│ ) else (
30│ pushd "%x%" 2>nul
31│ if errorlevel 1 set "directory=." &goto :EOF
32│ set "directory=%x%"
33│ set /a flag_d+=1
34│ popd
35│ )
36│goto :EOF
在前六行中,flag_n 与 flag_d 分别是记录参数中数字和目录个数的两个变量并在以后使用,其余不作过多解释。重点看看第7行到第17行,这是一个 if...else... 分支结构,第一个分支又被分割成为了两部分,p1,p2两个变量分别记录了 demo.cmd 所接收的参数1和参数2,所以整个部分被分成了可以用参数个数描述的,即无参数,一个参数,和两个参数三种情况。分别看看每种分支情况都执行了什么操作。
先说第9行也就是无参数的情况,语句含义为将变量 directory 赋值为“.”,有必要细说一下这条语句,既然没有任何参数输入到 demo.cmd 为什么还要设置变量 directory 呢?这样做的目的是给 directory 变量设置一个默认值,在以后的调用中如:dir %directory% ;for /r "%directory%" in (*.*) do ....这样类似的命令中即使 demo.cmd 没有接收到路径参数也不会出错,因为有这个默认的“.”,也就是使其在缺省状态下代表当前目录。当然是否确实有必要这样做要看你以后的命令如何使用 directory 这个变量。由于上面的代码只是一个参数接收的演示,也就没有后续的相关操作。如果你不需要对 directory 防空设计,可以将第8-10行替换为 “if defined p1 (” 将其简化,而只保留下一个分支。
下面谈谈上段提到的下一个分支,也就是第二个 if 语句的 else 部分,即一个参数的情况。因为这一个参数的内容仍然会是路径、数字其中之一,所以还需将变量 directory 赋值为“.”,以防碰到的参数是数字,也就是第11行的功能。再看看第12行,以 p1 为参数跳转到标签 _test ,完成一次类似功能函数的调用。我们不知道完成了什么功能,先放放一放,往下看。下面到了第一个 if 语句的 else 部分,即两个参数的情况。发现分别以 p1 p2 调用了两次 _test 函数。这回我们有必要研究一下 _test 函数到底完成了什么功能。
直接跳转到第23行,看语句首先将上面调用时发送的参数赋值给变量 x ,接下来执行一次算术操作将值赋给变量 y ,先加一再减一,有些不知所以。再往下看看 if 语句的第一个分支,如果 x 与 y 的值相等,将 x 值赋给变量 number ,并且将 flag_n 加一,我们还记得上文提及 flag_n 是记录参数中数字个数的变量,看来 x 与 y 的值相等,就断定 x 也就是上面调用时传送的参数是一个数字。为什么会这样?第25行应该是关键,在这里有一个小技巧,先插一段 set 帮助:
“在表达式中的任何非数字字符串键作为环境变量名称,这些环境变量名称的值已在使用前转换成数字。如果指定了一个环境变量名称,但未在当前环境中定义,那么值将被定为零。这使您可以使用环境变量值做计算而不用键入那些 % 符号来得到它们的值。”
现在清楚 set /a "y=x+1-1" 这一句的执行过程了吧! x 被替换为它自身变量值参与运算,当 x 值为数字时先加一再减一其值不变也就是 y=x ;当 x 值为非数字时其值将被定为零,先加一再减一后即 y=0 。所以据此也就可以判断 x 值是否为数字了。细心人会猜想要是 x 本身等于 0 怎么办,这是特殊情况可以在 set /a 句前加以判断,改变程序执行顺序完成指定操作。但是我们这种将变量直接参与数值运算的处理方法也有局限性,比如 x 值 为 0123 会被判断为非数字,这是因为以 0 开头的数字会被解释为 8 进制数字其值为 83 。所以我们可以正确判断的只是自然数字,有方法能回避或者解决吗?我们待会再谈这个问题。
接下来我们再来看 _test 函数 if 语句的 else 分支,第30行 pushd "%x%" 会保存当前目录,供后续命令 popd 命令使用,并切换到 x 值所表示的目录,简单说就是保存当前目录,并更改目录。下一行根据 pushd 命令的执行情况决定程序的转向,错误的话也就是非目录情况仍然设置 directory 为“.”并退出函数。第32-34行很简单 pushd 执行成功将 directory 设为 x 的值, flag_d 值增一,然后切换到被保存起来的目录。这样便完成了是否是目录的判断。看一下我们发现忽略了非数字非目录的错误输入情况,这只是为了更好的理解这个过程而做的忽略,你可以在开头部分设置一个 flag_o 变量,并在 if errorlevel 1 句增加 set /a flag_o+=1 来记录这种情况。当然为了便于理解和描述我用了并行执行多个命令的连接符“&”;实际中你可以用括号括起多条语句段来分别执行。
这样我们便实现了数字、目录和其他字符的判断,再回到主程序就好理解了,只是将我们保存的信息显示出来,实际应用中的话再供其他命令使用。想想我们还有什么遗漏情形,比如一个参数 456 是一个目录怎么办,我们可以在第27行前加一个是否为目录的判断?而存在 456 这个目录但本身是我们想要的一个数字怎么办?这是一个没法回答的问题,所以避免这样种种岐义情况最好的办法是要求输入全路径也就是文章开头提到的这个词,而不是我们文章中部一直在使用的目录这个词。我们再来谈谈以零开头的数字的问题,既然要求的是全路径,零开头肯定不是目录,我们用取子字符串命令循环替换掉前面的零再做判断。事实上我们有必要这样做吗?我不敢说没有,那要看你对程序的容错要求程度了。
回过头来再看看这种参数的处理方式,会发现很难应对多参数的复杂情况,更好的方式应该是 demo /A... /B... /C...这样的接收处理模式,用选项来限定参数。这样的好处是只要按限定符接收就行了,而不用将无顺序的参数交给批处理程序分析判断。这只是初步想法还不知是否能转成可行实用的批处理程序,欢迎朋友们一起来探讨。
补记,本来只是想记录一下碰到的问题来这,没想到罗嗦了那么多。如有纰漏,希望指正。
### A Little Discussion on Batch Processing Parameter Issues
Recently, I wrote a batch processing program and wanted the program to flexibly receive up to two parameters. However, I encountered difficulties during the process, such as how to handle different numbers of parameters and how to realize the judgment of parameter types. After some time of thinking and exploration, I finally solved these problems satisfactorily. Next, I will talk about this process. If you want to test the effect, please do it under the NT system.
First, let's explain the parameters that this batch processing program is supposed to receive. One parameter is a path, and the other is a number. Then there are the following several combination transformations:
1. Empty
2. Path
3. Number
4. Path + Number
5. Number + Path
6. Path + Path
7. Number + Number
The first five cases are the normal parameter combinations that the program needs to handle, and the latter two are the unexpected combinations. Let's first look at the following demo program and discuss the processing and implementation of this process together.
:: demo.cmd Demonstration of Batch Processing Parameter Handling ↑ for 2000, XP
:: by: Wuna ihe email: wunaihe@gmail.com 2005.11.17
1│@echo off
2│setlocal
3│set "p1=%~1"
4│set "p2=%~2"
5│set flag_d=0
6│set flag_n=0
7│if not defined p2 (
8│ if not defined p1 (
9│ set "directory=."
10│ ) else (
11│ set "directory=."
12│ call :_test "%p1%"
13│ )
14│) else (
15│ call :_test "%p1%"
16│ call :_test "%p2%"
17│ )
18│if %flag_n% == 2 echo The parameters are two numbers &goto :EOF
19│if %flag_d% == 2 echo The parameters are two directories &goto :EOF
20│echo The directory is: %directory% The number is: %number%
21│goto :EOF
22│
23│:_test
24│set "x=%~1"
25│set /a "y=x+1-1"
26│if "%y%" == "%x%" (
27│ set "number=%x%"
28│ set /a flag_n+=1
29│ ) else (
30│ pushd "%x%" 2>nul
31│ if errorlevel 1 set "directory=." &goto :EOF
32│ set "directory=%x%"
33│ set /a flag_d+=1
34│ popd
35│ )
36│goto :EOF
In the first six lines, flag_n and flag_d are two variables to record the number of numbers and directories in the parameters respectively and will be used later, and the rest will not be explained too much. Focus on lines 7 to 17. This is an if...else... branch structure. The first branch is further divided into two parts. The two variables p1 and p2 respectively record the parameter 1 and parameter 2 received by demo.cmd, so the entire part is divided into three situations that can be described by the number of parameters, namely no parameters, one parameter, and two parameters. Let's see what operations are performed in each branch situation respectively.
First, let's talk about the situation of no parameters in line 9. The statement means assigning the variable directory the value ".". It is necessary to explain this statement in detail. Since no parameters are input to demo.cmd, why set the variable directory? The purpose of this is to set a default value for the directory variable. In subsequent calls, such as dir %directory%; for /r "%directory%" in (*.*) do .... In such commands, even if demo.cmd does not receive the path parameter, there will be no error because there is this default ".", that is, it represents the current directory in the default state. Of course, whether it is necessary to do this in this way depends on how you use the directory variable in subsequent commands. Since the above code is just a demonstration of parameter reception, there are no subsequent related operations. If you don't need to design the directory to be empty, you can replace lines 8-10 with "if defined p1 (" to simplify it and only keep the next branch.
Next, let's talk about the next branch mentioned above, that is, the else part of the second if statement, that is, the situation of one parameter. Because the content of this one parameter will still be either a path or a number, it is necessary to assign the variable directory the value ".", just in case the parameter encountered is a number, that is, the function of line 11. Then look at line 12, which jumps to the label _test with p1 as the parameter to complete a call similar to a function. We don't know what function is completed, so let's put it aside and look down. Then comes the else part of the first if statement, that is, the situation of two parameters. It is found that the _test function is called twice with p1 and p2 respectively. Now we need to study what function the _test function actually completes.
Directly jump to line 23. First, the statement assigns the parameter sent above to the variable x. Then, an arithmetic operation is performed to assign the value to the variable y, adding 1 first and then subtracting 1, which is a bit confusing. Then, look at the first branch of the if statement. If the values of x and y are equal, assign the value of x to the variable number and add 1 to flag_n. We still remember that flag_n is the variable to record the number of numbers in the parameters. It seems that if the values of x and y are equal, it is determined that x, that is, the parameter sent above, is a number. Why is this? Line 25 should be the key. Here is a small trick. First, insert a set help:
"In any non-numeric string in the expression is treated as an environment variable name, and the value of these environment variable names is converted to a number before use. If an environment variable name is specified but not defined in the current environment, then the value will be set to zero. This allows you to use environment variable values for calculations without having to type those % symbols to get their values."
Now it is clear the execution process of the sentence set /a "y=x+1-1". The x is replaced by its own variable value to participate in the operation. When the x value is a number, adding 1 first and then subtracting 1 leaves its value unchanged, that is, y = x; when the x value is a non-number, its value will be set to zero, and after adding 1 first and then subtracting 1, y = 0. So based on this, it can also be judged whether the x value is a number. A careful person will guess what if x itself is 0. This is a special case. You can judge before the set /a sentence and change the program execution order to complete the specified operation. However, this processing method of directly participating the variable in numerical operation also has limitations. For example, the x value 0123 will be judged as a non-number, because the number starting with 0 will be interpreted as an octal number with a value of 83. So the natural numbers that we can correctly judge are only natural numbers. Is there a way to avoid or solve this problem? We will talk about this problem later.
Next, let's look at the else branch of the if statement in the _test function. Line 30 pushd "%x%" will save the current directory for subsequent commands to use the popd command, and switch to the directory represented by x. Simply put, it saves the current directory and changes the directory. The next line decides the program's turn according to the execution situation of the pushd command. If it is wrong, that is, the non-directory situation, it still sets directory to "." and exits the function. Lines 32-34 are very simple. If pushd is executed successfully, set directory to the value of x, increment flag_d by 1, and then switch to the saved directory. In this way, the judgment of whether it is a directory is completed. Let's see that we have ignored the error input situation of non-number and non-directory. This is just to better understand this process and is ignored. You can set a flag_o variable at the beginning and add set /a flag_o+=1 in the if errorlevel 1 sentence to record this situation. Of course, for the convenience of understanding and description, I used the connection符 "&" for executing multiple commands in parallel; actually, you can use parentheses to enclose multiple statement segments to execute them respectively.
In this way, we have realized the judgment of numbers, directories and other characters. Then it is easy to understand when returning to the main program, just display the information we saved, and in practical applications, it will be used for other commands. Think about what omissions we have. For example, what if one parameter 456 is a directory? We can add a judgment of whether it is a directory before line 27? And what if there is a directory 456 but it is a number we want? This is an unanswerable question. So the best way to avoid such ambiguous situations is to require entering the full path, which is the word mentioned at the beginning of the article, instead of the word directory we have been using in the middle of the article. Let's talk about the problem of numbers starting with zero. Since the required is the full path, numbers starting with zero must not be directories. We can use the substring extraction command to loop and replace the preceding zeros and then make a judgment. In fact, is it necessary for us to do this? I can't say no, that depends on the degree of fault tolerance you require for the program.
Looking back at this way of parameter processing, we will find that it is difficult to cope with the complex situation of multiple parameters. A better way should be the receiving and processing mode like demo /A... /B... /C..., using options to limit the parameters. The advantage of this is that you just need to receive according to the qualifier, instead of leaving the unordered parameters to the batch processing program for analysis and judgment. This is just an initial idea and I don't know whether it can be converted into a feasible and practical batch processing program. Friends are welcome to discuss together.
Postscript: Originally, I just wanted to record the problems I encountered here, but I didn't expect to be so wordy. If there are any omissions, I hope to be corrected.
|
|
2005-11-17 16:42 |
|
|
willsort
元老会员
         Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第 2 楼』:
使用 LLM 解释/回答一下
Re 无奈何:
很有见地的一篇主题,根据其讨论的内容和深度,相信可以归入(開發室) ,只是彼处对此能会心一笑的人太少了,还是暂时先放在这里讨论吧。
动态参数的支持,我在学习批处理之初便曾有接触,只是当时未及深入,疏漏自然难免。后来再编写那个文本遍历程序的命令行增强版(VisitCE)时,曾试图对此进行更深入的探索,但是一入其中,便觉如同幽魂迷宫,错综复杂,需要考虑和斟酌的东西太多了。此时,才对DOS命令行的灵活性有了另一番深入的体会。
关于多个动态参数的支持,我建议使用 :loop 和 goto loop 的循环对参数分析,这样多少可以避免程序陷入 if else 的迷魂阵中,这也是其他高级语言的代码处理参数的通常做法。对所有的参数都一视同仁,首先判断是否空,其次判断其所属类别,再次判断其是否有效,最后判断其是否可以保存(即是否已经保存或其他情形)。这样即使处理任意多个动态参数,也不需要对代码有太大的更改。
另外,将参数分为目录和数字的分类法,必然会导致参数的二义性问题,从而导致程序分析的复杂化,许多高级语言规定变量名不允许以数字起始,便基于此项原因(反例是DOS的环境变量)。想要避免它,就需要重新划分参数的类别,你所说的全路径便是一种折中的办法。
对于判断参数是否数字,如果允许使用外部命令,那么可以考虑 finstr 的正则表达式过滤。
最后,给出一个题目,大家讨论一下:如何在 MS-DOS下 实现相同的需求?
Re 无奈何:
A very insightful topic. Based on its content and depth, I believe it can be categorized into the (Development Room), but there are too few people who can appreciate it there, so let's temporarily discuss it here.
Regarding the support for dynamic parameters, I came into contact with it at the beginning of learning batch processing, but I didn't go deep at that time, so omissions were inevitable. Later, when I was writing the command-line enhanced version (VisitCE) of that text traversal program, I tried to explore it more deeply, but once I got into it, it was like a maze of ghosts, complicated, with too many things to consider and deliberate. At this time, I had a deeper understanding of the flexibility of the DOS command line.
Regarding the support for multiple dynamic parameters, I suggest using :loop and goto loop loops to analyze parameters, which can somewhat avoid the program falling into the maze of if else, which is also the usual practice for code handling parameters in other high-level languages. Treat all parameters equally, first judge whether it is empty, then judge its category, then judge whether it is valid, and finally judge whether it can be saved (that is, whether it has been saved or other situations). In this way, even if processing any number of dynamic parameters, there is no need to change the code too much.
In addition, the classification method of dividing parameters into directories and numbers will inevitably lead to the ambiguity problem of parameters, thus complicating the program analysis. Many high-level languages stipulate that variable names are not allowed to start with numbers, which is based on this reason (the counterexample is the environment variables of DOS). To avoid it, it is necessary to re-divide the categories of parameters. The full path you mentioned is a compromise.
For judging whether a parameter is a number, if external commands are allowed, you can consider the regular expression filtering of finstr.
Finally, give a question for everyone to discuss: How to achieve the same requirement under MS-DOS?
|

※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2005-11-17 18:31 |
|
|
无奈何
荣誉版主
      
积分 1338
发帖 356
注册 2005-7-15
状态 离线
|
   『第 3 楼』:
使用 LLM 解释/回答一下
和之者寡,如我猜想一样这果然是一个淡帖。本想续个下篇完结这个问题的讨论,也算作是学习批处理半年多来的总结,可我实在无力、无心完成了。
谢谢 willsort 兄的肯定与鼓励,你的建议让我获益颇多。
上篇文章中留了个尾巴,实在不爽,可我又无心再续。再贴一段批处理程序,算作上篇遗留问题的处理吧。这是我的某个程序的一段,部分更改后做成个演示程序。这段代码是我几次补充修改后的结果,可能有些乱,我不作解释了,因为对此感兴趣的朋友应该都能看明白。
:: demo2.cmd 批处理参数处理演示 2 2000、XP ↑
:: by:无奈何 email:wunaihe@gmail.com 2005.11.25
@echo off
rem xss
setlocal
set /a n=0,m=1
set /a I=0,F=0,V=0,L=0,O=0
:loop
set "_temp=%~1"
if "%_temp%" == "" goto :star
if "%m%" == "1" (
echo "%_temp%" |findstr/i /r "\</I\> \</F\> \</V\> \</L\> \</O\>" 2>nul 1>&2
if errorlevel 1 echo 非识别参数 “%_temp%” &goto :EOF
)
set /a n=n+1,m=m+1
if /i "%_temp%" == "/I" set /a I=1,F=0,V=0,L=0,O=0,n=1
if /i "%_temp%" == "/F" set /a I=0,F=1,V=0,L=0,O=0,n=1
if /i "%_temp%" == "/V" set /a I=0,F=0,V=1,L=0,O=0,n=1
if /i "%_temp%" == "/L" set /a I=0,F=0,V=0,L=1,O=0,n=1
if /i "%_temp%" == "/O" set /a I=0,F=0,V=0,L=0,O=1,n=1
if "%n%" == "2" (
if "%I%" == "1" set "directory_i=%_temp%" &set m=1
if "%F%" == "1" set "filter_f=%_temp%" &set m=1
if "%V%" == "1" set "filter_v=%_temp%" &set m=1
if "%L%" == "1" set "log=%_temp%" &set m=1
if "%O%" == "1" set "directory_o=%_temp%" &set m=1
)
shift
goto loop
:star
echo.directory_i %directory_i%
echo.filter_f %filter_f%
echo.filter_v %filter_v%
echo.log %log%
echo.directory_o %directory_o%
goto :EOF
Last edited by 无奈何 on 2005-11-27 at 15:02 ]
There are few who agree, just as I guessed, this is indeed a low - activity post. I originally wanted to continue with a next part to finish the discussion of this issue, and also to serve as a summary of more than half a year's study of batch processing, but I really don't have the energy or the heart to complete it.
Thanks to Brother willsort for the affirmation and encouragement, your suggestions have benefited me a lot.
There was a loose end in the previous article, which really makes me unhappy, but I have no heart to continue. I will post another section of batch processing program, as the handling of the remaining problem in the previous article. This is a section of my certain program, after partial changes, it is made into a demonstration program. This code is the result of my several supplements and modifications, which may be a bit messy, and I won't explain it, because friends who are interested in this should be able to understand it all.
:: demo2.cmd Batch processing parameter processing demonstration 2 Upward compatible with 2000, XP
:: by: Wu Naihe email: wunaihe@gmail.com 2005.11.25
@echo off
rem xss
setlocal
set /a n=0,m=1
set /a I=0,F=0,V=0,L=0,O=0
:loop
set "_temp=%~1"
if "%_temp%" == "" goto :star
if "%m%" == "1" (
echo "%_temp%" |findstr/i /r "\</I\> \</F\> \</V\> \</L\> \</O\>" 2>nul 1>&2
if errorlevel 1 echo Non - recognized parameter "%_temp%" &goto :EOF
)
set /a n=n+1,m=m+1
if /i "%_temp%" == "/I" set /a I=1,F=0,V=0,L=0,O=0,n=1
if /i "%_temp%" == "/F" set /a I=0,F=1,V=0,L=0,O=0,n=1
if /i "%_temp%" == "/V" set /a I=0,F=0,V=1,L=0,O=0,n=1
if /i "%_temp%" == "/L" set /a I=0,F=0,V=0,L=1,O=0,n=1
if /i "%_temp%" == "/O" set /a I=0,F=0,V=0,L=0,O=1,n=1
if "%n%" == "2" (
if "%I%" == "1" set "directory_i=%_temp%" &set m=1
if "%F%" == "1" set "filter_f=%_temp%" &set m=1
if "%V%" == "1" set "filter_v=%_temp%" &set m=1
if "%L%" == "1" set "log=%_temp%" &set m=1
if "%O%" == "1" set "directory_o=%_temp%" &set m=1
)
shift
goto loop
:star
echo.directory_i %directory_i%
echo.filter_f %filter_f%
echo.filter_v %filter_v%
echo.log %log%
echo.directory_o %directory_o%
goto :EOF
Last edited by 无奈何 on 2005-11-27 at 15:02 ]
|

☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul
|
|
2005-11-25 23:42 |
|
|
willsort
元老会员
         Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第 4 楼』:
使用 LLM 解释/回答一下
Re 无奈何:
知音难觅,古之良训,兄因此感怀可见也是性情中人。
以下是我的代码,主要针对于 MSDOS/Win9x 环境,在 NT’s 应该也没有什么大问题,当然未经过严格测试,我不能做保证的。
代码中没有做参数有效性的验证,也没有实现遇到重复开关的验证,不过在实际应用中,可以根据各类型参数的实际情况,比较简单地插入验证代码到相应的模块中。
兄的代码中,有以下几点疑问:
1、 set "_temp=%~1" ,我猜测将参数保存至变量的目的在于,剔除参数中的双引号,这是 %~1 的作用,但是我不明白为何将将变量名加参数都用引号括起。
2、变量 m n,我猜测它们的作用是标示参数的奇偶性,即表明参数是开关还是变量值,但是否可用一个变量的真假来标示?我的方案中因为是用双shift避免了开关和变量值的选择的,这样可能会引起 prog /i /o 这样的识别问题,但是如果在 SwitchI 中加入有效性验证,那么也可以避免。
3、set /a I=1,F=0,V=0,L=0,O=0,n=1 ,这样的设置会如何识别 prog /i input /o output /i input2 ?
:: ArgParse.bat - Parser of command line arguments
:: Will Sort - 2005-11-26 - WinXP_CMD/MSDOS7.10/MSDOS6.22
@echo off
:Init
for %%e in (directory_i directory_o filter_f filter_v log) do set %%e=
<img src="images/smilies/face-raspberry.png" align="absmiddle" border="0">arseLoop
if "%1"=="" goto Start
for %%s in (i I f F v V l L o O) do if "%1"=="/%%s" goto Switch%%s
echo Error: Invalid switch '%1'!
goto Quit
:SwitchI
if "%directory_i%"=="" set directory_i=%2
goto NextArg
:SwitchO
if "%directory_o%"=="" set directory_o=%2
goto NextArg
:SwitchF
if "%filter_f%"=="" set filter_f=%2
goto NextArg
:SwitchV
if "%filter_v%"=="" set filter_v=%2
goto NextArg
:SwitchL
if "%log%"=="" set log=%2
goto NextArg
:NextArg
shift
shift
goto ParseLoop
:Start
echo.directory_i %directory_i%
echo.directory_o %directory_o%
echo.filter_f %filter_f%
echo.filter_v %filter_v%
echo.log %log%
:Quit
for %%e in (directory_i directory_o filter_f filter_v log) do set %%e=
:end
Last edited by willsort on 2005-11-26 at 19:35 ]
Re 无奈何:
Seeking a kindred spirit is hard, an old adage. Brother's emotional response shows you're a man of sentiment.
The following is my code, mainly for MSDOS/Win9x environments, and it should be mostly fine for NT's too, though not strictly tested, so I can't guarantee it.
There's no validation of parameter validity in the code, and no verification for encountering duplicate switches. But in practical applications, you can relatively easily insert validation code into the relevant modules according to the actual situation of various types of parameters.
Brother's code has the following questions:
1. set "_temp=%~1", I guess the purpose of saving the parameter to a variable is to remove the double quotes in the parameter, which is the function of %~1, but I don't understand why both the variable name and the parameter are enclosed in quotes.
2. Variables m and n, I guess their role is to mark the parity of parameters, that is, to indicate whether the parameter is a switch or a variable value, but can it be marked with the true/false of a single variable? In my scheme, because I use double shift to avoid the selection of switches and variable values, this may cause problems in identifying prog /i /o, but if validity verification is added in SwitchI, it can also be avoided.
3. set /a I=1,F=0,V=0,L=0,O=0,n=1, how will this setting recognize prog /i input /o output /i input2?
:: ArgParse.bat - 命令行参数解析器
:: Will Sort - 2005-11-26 - WinXP_CMD/MSDOS7.10/MSDOS6.22
@echo off
:Init
for %%e in (directory_i directory_o filter_f filter_v log) do set %%e=
:ParseLoop
if "%1"=="" goto Start
for %%s in (i I f F v V l L o O) do if "%1"=="/%%s" goto Switch%%s
echo Error: Invalid switch '%1'!
goto Quit
:SwitchI
if "%directory_i%"=="" set directory_i=%2
goto NextArg
:SwitchO
if "%directory_o%"=="" set directory_o=%2
goto NextArg
:SwitchF
if "%filter_f%"=="" set filter_f=%2
goto NextArg
:SwitchV
if "%filter_v%"=="" set filter_v=%2
goto NextArg
:SwitchL
if "%log%"=="" set log=%2
goto NextArg
:NextArg
shift
shift
goto ParseLoop
:Start
echo.directory_i %directory_i%
echo.directory_o %directory_o%
echo.filter_f %filter_f%
echo.filter_v %filter_v%
echo.log %log%
:Quit
for %%e in (directory_i directory_o filter_f filter_v log) do set %%e=
:end
Last edited by willsort on 2005-11-26 at 19:35 ]
|

※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2005-11-26 19:32 |
|
|
无奈何
荣誉版主
      
积分 1338
发帖 356
注册 2005-7-15
状态 离线
|
『第 5 楼』:
使用 LLM 解释/回答一下
to: willsort
高山流水觅知音,能有兄的回复倍感欣喜。
1、“%~1”如你所说确实是想剔除双引号,如果一个变量的值可能有双引号也可能没有,会造成一些调用的不便。如果一个变量“ABC”值含有空格、分号这样的字符时调用标签函数,call :test %ABC% 势必会将 ABC 拆分为多个参数,所以会这样用 call :test "%ABC%" 这样就会造成传递过去的参数会有双引号包围和两个双引号包围的情况。在我应用中还碰到其他的一些问题,一时想不起来了。我也就养成习惯统一去除双引号了。
还有用双引号将变量名和值括起来有几点好处,一是这样的话可以使用含有空格的变量名如: set "A B=A-B",二是将变量赋值时防止尾部会有不小心键入的空格如:set "A=" 。这些小技巧可以避免一些不必要的麻烦。
2、变量 m 与 n 的作用是标示是否是参数标示(开关)和参数变量,但不是以奇偶性来判断的,我最初也是用一个变量采用取余的方法按奇偶判断,出现了你提及的连续出现两个有效参数标示时其后部分全部出错的情况。n 的作用是会确定有效参数标示后紧跟的一个非有效参数标示为参数变量。m 的作用刚好相反,它会认定参数变量其后紧跟的是一个参数标示。
3、设置 I,F,V,L,O 这几个标志变量的作用就是想让程序能够正确接收无序的并且个数不固定的参数。当一个有效参数标示到来时,对应的标志变量置 1 ,其他标志变量置 0 ;进入下一次循环,当一个有效参数变量到来时,根据标志变量是否为 1 ,就可以判断上次接收到的是哪一个参数标示,然后设置对应的变量值。碰到你提及的有两个重复参数的时候,后一个的值会替代前一次接收的值,也就是以最后输入为准。还有就是当想要标志变量只作开关而无参数变量时,可以直接在最初的判断处添加赋值语句解决这种问题。
我仔细看了兄的示例,代码确实优秀,流畅程度远远超过了我的拙作。如果再多一层判断完善单步走与双步走的两种分支,也可以很好的解决标志变量只作开关的情况。
Last edited by 无奈何 on 2005-11-27 at 13:08 ]
to: willsort
Seeking a bosom friend like the legend of "High Mountains and Flowing Water", I am extremely delighted to receive your reply.
1. As you said, "%~1" is indeed to remove the double quotes. If a variable's value may or may not have double quotes, it will cause some inconvenience in calling. When a variable "ABC" contains characters like spaces and semicolons and you call a label function, "call :test %ABC%" will definitely split ABC into multiple parameters, so "call :test "%ABC%"" is used, which will cause the passed parameter to be surrounded by double quotes and sometimes by two pairs of double quotes. I also encountered some other problems in my application, but I can't remember them for the moment. So I also developed the habit of uniformly removing double quotes.
There are also several advantages to enclosing the variable name and value with double quotes. First, in this way, you can use a variable name with spaces, such as "set "A B=A-B"". Second, when assigning a variable, it prevents accidental spaces at the end, such as "set "A="". These small tricks can avoid some unnecessary troubles.
2. The roles of variables m and n are to mark whether they are parameter markers (switches) and parameter variables, but not judged by parity. I initially also used a variable to judge by remainder according to parity, and the situation where all subsequent parts were completely wrong occurred when two valid parameter markers appeared continuously. The role of n is to determine that a non-valid parameter marker immediately following a valid parameter marker is a parameter variable. The role of m is just the opposite; it will recognize that a parameter variable is immediately followed by a parameter marker.
3. The role of setting the flag variables I, F, V, L, O is to make the program correctly receive parameters that are out of order and of an indefinite number. When a valid parameter marker arrives, the corresponding flag variable is set to 1, and other flag variables are set to 0; entering the next loop, when a valid parameter variable arrives, according to whether the flag variable is 1, you can judge which parameter marker was received last time, and then set the corresponding variable value. When there are two repeated parameters as you mentioned, the value of the latter will replace the value of the previous one, that is, the last input prevails. Also, when you want a flag variable to only act as a switch without a parameter variable, you can directly add an assignment statement at the initial judgment to solve this problem.
I have carefully read your example. The code is indeed excellent, and the fluency far exceeds my crude work. If there is one more layer of judgment to perfect the two branches of single-step and double-step, it can also well solve the situation where the flag variable only acts as a switch.
Last edited by 无奈何 on 2005-11-27 at 13:08 ]
|

☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul
|
|
2005-11-26 23:35 |
|
|
willsort
元老会员
         Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第 6 楼』:
使用 LLM 解释/回答一下
Re 无奈何:
很抱歉!因为各种主观和客观原因,我的回复被迫推迟了。
1、兄对 set "_temp=%~1" 的解释确实有理,尤其是防止尾部空格的提示;因为我长期在 MSDOS/Win9x 下编写批处理代码,对带空格参数和带引号参数接触机会不多,所以考虑尚未周全。
经过测试,发现 ntcmd.set 对命令行中的引号处理很周到,对 set _temp=This is "test string" ! 或者 set "_temp=This is "test string" !" 等情况都能恰当的处理;但是在 MSDOS / Win9x 下就会出现很多问题。另外,无论是在 MSDOS / 9X_COMMAND 下,还是在 XP_CMD 下,set var name=value 的用法都是有效的。
2、对 m n 的作用我已基本理解,双变量分别标示开关项和非开关项确实是必要的。
3、起初,我认为你这样的设置会允许开关的重复设定,而这通常是错误的用法,而你在主楼中提到的第6/7组合也被你认定是“不期望的”。不过后来我想到在某些场合中可能会需要这样的用法,这我曾在类 unix 的命令行中和一些复杂的批处理中见到过,所以也就默认了它的存在。
4、关于我的代码,最初设计这个程序时,我是将 prog /i /o output 和 prog /i input /i input2 都列为错误参数用法的。现在想来, prog /i /o output 的情形还是很常用的,尤其是某些参数只是作为启闭某项功能特性的开关(Switch)时,所以将它按照你所说的单双步分法作了简单的改进。
此外,我的程序也允许 prog /i input1 /i input2 这种情形,不过与你的代码正相反,它只取第一个设定值;如你所言,想要改成取最后一个也很简单,只需要将判断是否已设置的 if 条件删除即可;而如果要禁止这种情形,也只需要将条件取反后进行错误处理即可。但要处理未必含有设定值的开关时就比较麻烦,需要对参数进行检查了。下面是新的代码,在线完成,未经测试!
:: ArgParse.bat - V2 - Parser of command line arguments
:: Will Sort - 2005-11-30 - WinXP_CMD/MSDOS7.10/MSDOS6.22
@echo off
:Init
for %%e in (directory_i directory_o filter_f filter_v log) do set %%e=
<img src="images/smilies/face-raspberry.png" align="absmiddle" border="0">arseLoop
if "%1"=="" goto Start
for %%s in (l L i I o O f F v V) do if "%1"=="/%%s" goto Switch%%s
echo Error: Invalid switch '%1'!
goto Quit
:: 一个有设定值的开关,如果重复设定将取最后一个
:SwitchI
set directory_i=%2
goto Next2Arg
:: 一个有设定值的开关,如果重复设定将取第一个
:SwitchO
if "%directory_o%"=="" set directory_o=%2
goto Next2Arg
:: 一个有设定值的开关,如果重复设定将抛出错误后终止程序
:SwitchF
if not "%filter_f%"=="" echo Error: Replicative switch '%1'!
if not "%filter_f%"=="" goto Quit
set filter_f=%2
goto Next2Arg
:: 一个可能有设定值的开关,如果未在其后设定值,将取默认值
:SwitchV
set filter_v=default
for %%s in (l L i I o O f F v V) do if "%2"=="/%%s" goto NextArg
if not "%2"=="" set filter_v=%2
goto Next2Arg
:: 一个没有设定值的开关,只有启闭功能,重复设定将反复取反
:SwitchL
if "%log%"=="" set _log=on
if "%log%"=="on" set _log=off
if "%log%"=="off" set _log=on
set log=%_log%
set _log=
goto NextArg
:Next2Arg
shift
:NextArg
shift
goto ParseLoop
:Start
echo.directory_i %directory_i%
echo.directory_o %directory_o%
echo.filter_f %filter_f%
echo.filter_v %filter_v%
echo.log %log%
:Quit
for %%e in (directory_i directory_o filter_f filter_v log) do set %%e=
:end
Last edited by willsort on 2005-11-30 at 12:24 ]
Re 无奈何:
I'm very sorry! Due to various subjective and objective reasons, my reply was forced to be delayed.
1. Brother's explanation of "set "_temp=%~1" is indeed reasonable, especially the prompt to prevent trailing spaces; because I have been writing batch code under MSDOS/Win9x for a long time, and I don't have many opportunities to contact parameters with spaces or quotes, so I didn't consider it comprehensively.
After testing, it is found that ntcmd.set handles the quotation marks in the command line very comprehensively, and can properly handle cases like set _temp=This is "test string" ! or set "_temp=This is "test string" !"; but many problems will occur under MSDOS/Win9x. Also, whether under MSDOS/9X_COMMAND or XP_CMD, the usage of set var name=value is valid.
2. I have basically understood the role of m n. It is indeed necessary for the two variables to mark the switch items and non-switch items respectively.
3. At first, I thought that your setting would allow repeated setting of switches, and this is usually an incorrect usage, and the 6/7 combination you mentioned in the main post is also considered "unexpected" by you. But later I thought that such usage might be needed in some occasions, which I have seen in command lines similar to unix and some complex batch processing, so I just accepted its existence.
4. Regarding my code, when I originally designed this program, I listed both prog /i /o output and prog /i input /i input2 as wrong parameter usages. Now it occurs to me that the situation of prog /i /o output is still very common, especially when some parameters are just switches to turn on or off certain functional features, so I made simple improvements according to the single-step and two-step classification you mentioned.
In addition, my program also allows the situation of prog /i input1 /i input2, but opposite to your code, it only takes the first set value; as you said, it is very simple to change it to take the last one, just delete the if condition for judging whether it has been set; and if you want to prohibit this situation, you just need to reverse the condition and perform error handling. But it is more troublesome to handle switches that may not contain set values, and you need to check the parameters. The following is the new code, completed online, not tested!
:: ArgParse.bat - V2 - Parser of command line arguments
:: Will Sort - 2005-11-30 - WinXP_CMD/MSDOS7.10/MSDOS6.22
@echo off
:Init
for %%e in (directory_i directory_o filter_f filter_v log) do set %%e=
:ParseLoop
if "%1"=="" goto Start
for %%s in (l L i I o O f F v V) do if "%1"=="/%%s" goto Switch%%s
echo Error: Invalid switch '%1'!
goto Quit
:: A switch with a set value, if set repeatedly, will take the last one
:SwitchI
set directory_i=%2
goto Next2Arg
:: A switch with a set value, if set repeatedly, will take the first one
:SwitchO
if "%directory_o%"=="" set directory_o=%2
goto Next2Arg
:: A switch with a set value, if set repeatedly, will throw an error and terminate the program
:SwitchF
if not "%filter_f%"=="" echo Error: Replicative switch '%1'!
if not "%filter_f%"=="" goto Quit
set filter_f=%2
goto Next2Arg
:: A switch that may have a set value, if no value is set after it, will take the default value
:SwitchV
set filter_v=default
for %%s in (l L i I o O f F v V) do if "%2"=="/%%s" goto NextArg
if not "%2"=="" set filter_v=%2
goto Next2Arg
:: A switch without a set value, only has on/off function, repeated setting will toggle repeatedly
:SwitchL
if "%log%"=="" set _log=on
if "%log%"=="on" set _log=off
if "%log%"=="off" set _log=on
set log=%_log%
set _log=
goto NextArg
:Next2Arg
shift
:NextArg
shift
goto ParseLoop
:Start
echo.directory_i %directory_i%
echo.directory_o %directory_o%
echo.filter_f %filter_f%
echo.filter_v %filter_v%
echo.log %log%
:Quit
for %%e in (directory_i directory_o filter_f filter_v log) do set %%e=
:end
Last edited by willsort on 2005-11-30 at 12:24 ]
|

※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2005-11-29 17:34 |
|
|
无奈何
荣誉版主
      
积分 1338
发帖 356
注册 2005-7-15
状态 离线
|
『第 7 楼』:
使用 LLM 解释/回答一下
to:willsort
事实上 prog /i input1 /i input2 这种情况取前者与后者都是合理的,只是策略问题,完全可以怎么方便怎么来。
兄的下面一段代码,按你的功能提示来看好像漏掉了一种可能情况。
:SwitchV
for %%s in (l L i I o O f F v V) do if "%2"=="/%%s" set filter_v=default
for %%s in (l L i I o O f F v V) do if "%2"=="/%%s" goto NextArg
set filter_v=%2
goto Next2Arg
测试:prog /i input1 /v 发现并未按设想的赋值。可以加一条语句如下:
:SwitchV
for %%s in (l L i I o O f F v V) do if "%2"=="/%%s" set filter_v=default
for %%s in (l L i I o O f F v V) do if "%2"=="/%%s" goto NextArg
set filter_v=%2
if "%2"=="" set filter_v=default
goto Next2Arg
还有一个疑问,相同条件的语句兄为什么不作合并。如:
for %%s in (l L i I o O f F v V) do (
if "%2"=="/%%s" set filter_v=default
if "%2"=="/%%s" goto NextArg
)
这样可以减少一次循环,或者更简洁的将 if 句也合并,是兼容性的考虑吗?我不了解 DOS 下的问题。
to: willsort
In fact, in the case of prog /i input1 /i input2, both taking the former and the latter are reasonable, just a matter of strategy, and you can completely do whatever is convenient.
Brother's following code seems to have missed a possible situation according to your function prompt.
:SwitchV
for %%s in (l L i I o O f F v V) do if "%2"=="/%%s" set filter_v=default
for %%s in (l L i I o O f F v V) do if "%2"=="/%%s" goto NextArg
set filter_v=%2
goto Next2Arg
Test: prog /i input1 /v was found not to be assigned as envisioned. You can add a statement as follows:
:SwitchV
for %%s in (l L i I o O f F v V) do if "%2"=="/%%s" set filter_v=default
for %%s in (l L i I o O f F v V) do if "%2"=="/%%s" goto NextArg
set filter_v=%2
if "%2"=="" set filter_v=default
goto Next2Arg
There is also a question, why didn't brother merge the statements with the same conditions. Such as:
for %%s in (l L i I o O f F v V) do (
if "%2"=="/%%s" set filter_v=default
if "%2"=="/%%s" goto NextArg
)
This can reduce one loop, or more concisely merge the if statements. Is it a consideration of compatibility? I don't understand the problems under DOS.
|

☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul
|
|
2005-11-29 21:21 |
|
|
willsort
元老会员
         Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第 8 楼』:
使用 LLM 解释/回答一下
Re 无奈何:
1、prog /i input1 /v 确实是个问题,你的修改是必要的;而且真正要应用的时候,还需要防止 /x /y 或其他无效的开关情形,此时进行有效性验证就是必须的了。
2、两句同样的 for + if 确实是出于兼容性考虑,在 MSDOS / Windows 下,是不支持语句块的。虽然通过特殊的方法可以使两句合并,但是这里并不采用,一方面是兼容性的考虑,另一方面是可阅读性的考虑。
3、prog /i input1 /i input2 这种情况,取前者与后者适合于不同的应用场合。
比如在某些场合,我们可能会使用变量来保存带参数的命令行,然后在以后的某个环境下引用它,此时我们可能需要改变某个开关或参数,却出于某些原因无法修改变量,此时就需要取后者的策略,这样我们可以在引用变量的后面加上新的开关或参数来改变程序的运行状态。
至于取前者的策略则比较多见,但一般没有特别的目的性。但有一重特殊的情况是与上面正相反,我们可能会使用变量保存命令行的部分参数,然后在以后的某个环境下引用它,此时我们可能需要固定某个开关或参数,却出于某些原因无法修改变量,此时需要取前者的策略。或者某些程序会以各种形式预置一些的常用的命令行用法,而且不欲用户有意或无意的修改这些用法,则也需要取前者的策略。这类似于某些 unix 类程序中的 -- 命令行终止参数。
另外,刚注意到你的新签名,确实富有创意和技巧,只是文辞似乎略显伤感了些,恐怕会给论坛的新人带来负面的影响吧。玩笑而已 <img src="images/smilies/face-laugh.png" align="absmiddle" border="0">
Last edited by willsort on 2005-11-29 at 22:26 ]
Re 无奈何:
1. The issue with prog /i input1 /v is indeed a problem, and your modification is necessary; when actually applying it, it is also necessary to prevent situations like /x /y or other invalid switches, and at this time, validity verification is essential.
2. The two identical for + if statements are indeed due to compatibility considerations. In MSDOS / Windows, statement blocks are not supported. Although the two statements can be combined through special methods, it is not adopted here. On one hand, it is for compatibility considerations, and on the other hand, it is for readability considerations.
3. In the case of prog /i input1 /i input2, taking the former and the latter is suitable for different application scenarios.
For example, in some scenarios, we may use a variable to save a command line with parameters, and then refer to it in a certain subsequent environment. At this time, we may need to change a certain switch or parameter, but for some reason, we cannot modify the variable. At this time, we need to adopt the strategy of taking the latter, so that we can add new switches or parameters after referring to the variable to change the running state of the program.
As for the strategy of taking the former, it is more common, but generally has no special purpose. But there is a special case opposite to the above. We may use a variable to save part of the parameters of the command line, and then refer to it in a certain subsequent environment. At this time, we may need to fix a certain switch or parameter, but for some reason, we cannot modify the variable. At this time, we need to adopt the strategy of taking the former. Or some programs may pre-set some common command line usages in various forms, and do not want users to intentionally or unintentionally modify these usages, then the strategy of taking the former is also needed. This is similar to the -- command line termination parameter in some unix-like programs.
In addition, I just noticed your new signature, which is indeed creative and skillful, but the wording seems a bit sentimental, and I am afraid it may bring a negative impact on the new users of the forum. Just a joke :)
Last edited by willsort on 2005-11-29 at 22:26 ]
|

※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2005-11-29 22:19 |
|
|
无奈何
荣誉版主
      
积分 1338
发帖 356
注册 2005-7-15
状态 离线
|
『第 9 楼』:
使用 LLM 解释/回答一下
哈哈,以后就用你的这个构架了,给个授权吧!
我的签名确实花了一些心力,语句我尽量的精简,想让其保持功能的前提下拥有最少字符,这是我目前能做到的最好情况(%ComSpec% 替换为 cmd 不算),当然也就没有了可读性,故弄玄虚增加点神秘感。再者,无奈何不是一种持久的人生态度也不是现状的反映,可以理解为对种种不能为不可为之事的解嘲、劝抚,或于己事或于人事,多一些自抚调整少一些空劳抱怨。映于己映于人,也有太多的体现。伤感是肯定的,也显低调,但希望的不是低沉。我最初的词句是终是无可奈何,发觉不是我的本意,悄悄改了一字。
Haha, I'll use your framework from now on. Give me a license!
My signature really took some effort. I tried to be as concise as possible, wanting it to have the least number of characters while maintaining functionality. This is the best I can do right now (replacing %ComSpec% with cmd doesn't count). Of course, it lacks readability and is made a bit mysterious. Moreover, helplessness is not a lasting attitude towards life nor a reflection of the current situation. It can be understood as a self - mocking and comforting for various things that can't be done or shouldn't be done, whether it's about oneself or others. Do more self - comfort and adjustment and less idle complaining. It is also reflected a lot in oneself and in others. Sadness is definitely there, and it's also low - key, but what is hoped for is not depression. My original words were "Eventually, it's helpless", but I found it wasn't my original intention, so I quietly changed one word.
|

☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul
|
|
2005-11-30 00:19 |
|
|
willsort
元老会员
         Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第 10 楼』:
使用 LLM 解释/回答一下
Re 无奈何:
我的代码既没有声明 Copyright ,也没有附加任何 License ,所以也就不存在授权的问题,你当然可以自由的使用它。对网络自由共享的精神我是很欣赏的。
但是,一个好的框架或代码是需要经过反复测试和不断改进后才能正式应用的,而我的这个代码只是在线编写的一段代码,很可能存在许多潜在的问题和不完善。
昨夜入眠之前,就突然醒起一个地方可再做一下改进,就是你提到的双 for 语句处,我将前一个 for 省略了。代码不再重贴,只是编辑了6楼的原 V2 版代码。
Re 无奈何:
My code neither declares Copyright nor attaches any License, so there is no issue of authorization. Of course, you can use it freely. I appreciate the spirit of free sharing on the network.
However, a good framework or code needs to be formally applied only after repeated testing and continuous improvement. And my code is just a piece of code written online, which may have many potential problems and imperfections.
Before falling asleep last night, I suddenly woke up to a place that can be improved again, that is, the double for statement you mentioned. I omitted the previous for. The code is not reposted, just the original V2 version code on floor 6 is edited.
|

※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2005-11-30 10:35 |
|
|
maya0su
中级用户
  
积分 241
发帖 131
注册 2005-9-28
状态 离线
|
『第 11 楼』:
使用 LLM 解释/回答一下
苦者律己,行者无奈……
人生本就是一件痛苦的事,可是生来为人,我们不能沉沦,只有振作,吾爱吾爱之人……奈何花凋零……
无奈何兄的贴子我仔细反复看了看,最终的结果是我不参与讨论,因为我是今天才发现的这个帖子……而我的能力也非常有限,对于你提出的问题只能再去研究……而willsort兄的回贴确实精彩,你们在问与答之间完成了最初所设想,可喜可贺……弟我只能替你们高兴!
网络的最初设想就是自由和共享,可是现在网络成了人圈钱的工具,实在让我辈心寒,本着自由和共享的精神我谨希望以我们的微薄之力来延续这重种共享和自由,无奈何兄的签名我测了测,很有意思!
试出一个题目:能不能写个批处理程序,用一个字一个字的显示方式,显示出一段话呢?而且是批处理,双击后在窗口显示这短话,完成后屏幕暂停!
仅是想和兄们做个游戏,关注不关注无所谓……博君一笑而!
Those who suffer discipline themselves, those who act are helpless...
Life is inherently a painful thing, but since we are born as human beings, we cannot sink, we can only振作up, my beloved ones... But alas, flowers wither...
I carefully read Brother Wunaihe's post repeatedly. In the end, I won't participate in the discussion because I just discovered this post today... And my ability is very limited, and I can only study further for the questions you raised... And Brother Willsort's reply is really wonderful, you completed the initial设想between asking and answering, congratulations! I can only be happy for you!
The original vision of the Internet was freedom and sharing, but now the Internet has become a tool for people to make money, which really makes us old folks feel cold. Based on the spirit of freedom and sharing, I sincerely hope to use our meager efforts to continue this kind of sharing and freedom. Brother Wunaihe's signature I tested, it's very interesting!
Try to come up with a question: Can you write a batch processing program to display a passage in a way of displaying one character at a time? And it's a batch file, double-click to display this short passage in the window, and pause the screen after completion!
Just want to play a game with brothers, whether you pay attention or not doesn't matter... Just to make you smile!
|

房东说:这娃是个好孩子! |
|
2006-1-16 23:43 |
|
|
mrhjzhang
初级用户
 
积分 100
发帖 39
注册 2005-10-27
状态 离线
|
|
2006-1-19 16:45 |
|
|
220110
荣誉版主
      
积分 718
发帖 313
注册 2005-9-26
状态 离线
|
『第 13 楼』:
使用 LLM 解释/回答一下
试出一个题目:能不能写个批处理程序,用一个字一个字的显示方式,显示出一段话呢?而且是批处理,双击后在窗口显示这短话,完成后屏幕暂停!
Re maya0su:
参见无奈何的个人签名。
但其代码真让人晕。呵
希望无奈何朋友能整理出一个易看点的格式。
Last edited by 220110 on 2006-2-4 at 16:54 ]
Try to come up with a question: Can you write a batch program that displays a passage one character at a time? And it's a batch file, which, when double-clicked, displays this passage in the window and pauses the screen when done!
Re maya0su:
Refer to the personal signature of Wunaaihe.
But its code is really confusing. Hehe
Hope friend Wunaaihe can organize it into a more readable format.
Last edited by 220110 on 2006-2-4 at 16:54 ]
|
|
2006-2-2 10:26 |
|
|
zah98
新手上路

积分 9
发帖 4
注册 2006-10-22
状态 离线
|
『第 14 楼』:
使用 LLM 解释/回答一下
支持一下,有点看不懂
Support it's a bit hard to understand
|
|
2006-10-22 11:40 |
|
|
gxfc
新手上路

积分 17
发帖 11
注册 2006-10-22
状态 离线
|
|
2006-10-22 13:27 |
|
|