将函数的第二个参数读入数组
Posted
技术标签:
【中文标题】将函数的第二个参数读入数组【英文标题】:Read second parameter of a function into an array 【发布时间】:2013-11-17 20:19:11 【问题描述】:我编写了以下代码,完全符合我的要求:
@echo off
setlocal enabledelayedexpansion
set /a i=0
set in="This is line 1", "This is line 2"
for %%h in (%in%) do (
set /a i+=1
set "val[!i!]=%%h"
)
set out=
for /l %%n in (1,1,!i!) do (
set out=!out! !val[%%n]! ^& vbcrlf ^& _)
echo !out:~1,-12!
它获取 %in% 变量的值并将每个逗号分隔的行读取到数组的一个元素中,然后对其进行一些字符串连接并吐出一个新字符串。现在,当我尝试将其转换为函数时,它失败了,因为 %2 被解析为参数。我需要将 %2 解析为具有可变数量值的单个逗号分隔字符串。这个简单的测试不起作用:
call :Test Title "This is line 1","This is line 2" "arg3"
exit /b
:Test arg1 arg2 arg3
set /a i=0
for %%h in (%2) do (
set /a i+=1
set "val[!i!]=%%h"
)
set out=
for /l %%n in (1,1,!i!) do (
set out=!out! !val[%%n]! ^& vbcrlf ^& _)
echo %1 !out:~1,-12! %3
exit /b
我唯一能想到的就是使用 %* 并将分隔符更改为独特的东西,但如果可能的话,我宁愿避免这样做。
【问题讨论】:
【参考方案1】:1。切换中间参数
这将单独留下%1
,并转移所有中间参数,当没有更多参数时停止,并将最后一个参数留在%3
。
@echo off
setlocal
call :Test One "Two","Three" Four
endlocal
exit /b 0
:Test <Title> <Lines...> <LastArg>
echo %2
set "Temp=%4"
if defined Temp shift /2 & goto Test
echo %1
echo %3
exit /b 0
输出
"Two"
"Three"
One
Four
2。将字符串放入变量中,并传递变量名
@echo off
setlocal EnableDelayedExpansion
set "String="Two","Three""
call :Test One String Four
endlocal
exit /b 0
:Test <a> <b> <c>
echo %1
echo !%2!
echo %3
exit /b 0
输出
One
"Two","Three"
Four
这是我想到的前两个解决方案。
更新
这是使用内部循环 :__Test
应用于您的代码的 shift 方法
@echo off
setlocal EnableDelayedExpansion
call :Test Title "This is line 1","This is line 2" "arg3"
endlocal
exit /b 0
:Test <arg1> <arg2[,...]> <arg3>
set "i=0"
:__Test
set /a "i+=1"
set "val[!i!]=%2"
set "tempvar=%4"
if defined tempvar shift /2 & goto __Test
set "out="
for /l %%n in (1,1,!i!) do (
set out=!out! !val[%%n]! ^& vbcrlf ^& _)
echo %1 !out:~1,-12! %3
exit /b 0
【讨论】:
谢谢大卫。 shift 选项似乎是要走的路,但我不知道如何在我的代码中实现它。 @MattWilliamson 我用一个例子更新了我的答案。 @dbenham 更新示例是否有助于阐明方法 1?我很重视您的输入 dbenham,因为您是批处理文件方面的专家。 好的,我想我理解这个概念了。请注意,这不适用于多个列表参数。我建议通过重新排列参数来简化事情。我会将列表放在最后,以便从 3 开始的所有参数都在列表中,并按照您的建议使用 SHIFT 循环它们。 我现在明白了。我试图在 for 循环内进行转换。谢谢大卫!【参考方案2】:对于一般解决方案,通过引用传递值(将值存储在变量中并传递变量名称)是最佳选择。这与 David Ruhmann 的第二个选项相同。
还有另一种方法,但它需要调用者做更多的工作。您可以要求将参数值中的所有引号加倍,然后将整个参数括在另一组引号中。在函数中,将所有""
替换为"
以获得所需的值。在我学会了通过引用传递值之前,我曾经使用过这种方法。
@echo off
setlocal enableDelayedExpansion
call :Test Title """This is line 1"",""This is line 2""" "arg3"
exit /b
:Test arg1 arg2 arg3
set "arg2=%~2"
set "arg2=%arg2:""="%"
echo arg1=%1
echo arg2=%arg2%
echo arg3=%3
更新
通过引用传递值是传递包含标记分隔符和引号的复杂值的最佳选择。
但是 OP 对作为单个参数的值列表并不真正感兴趣,因为使用 FOR 循环将它们拆分。如果任何值包含*
或?
,FOR 循环可能会遇到问题。
我现在看到,对于这种特殊情况,最好将列表移动到末尾,这样从 3 开始的所有参数都是列表的一部分。然后使用SHIFT /3
和GOTO
循环读取列表值。这基本上是 David Ruhmann 的选项 1。
【讨论】:
+1 很好的解释和洞察力。也感谢您对我的回答的投入。以上是关于将函数的第二个参数读入数组的主要内容,如果未能解决你的问题,请参考以下文章