Arrays 将函数的第二个参数读入数组

Arrays 将函数的第二个参数读入数组,arrays,batch-file,arguments,command-line-arguments,Arrays,Batch File,Arguments,Command Line Arguments,我编写了以下代码,其工作方式完全符合我的要求: @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]! ^&a

我编写了以下代码,其工作方式完全符合我的要求:

@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
,并在没有更多参数时停止所有中间参数,并将最后一个参数保留在
%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
2.将字符串放入变量并传递变量名 这是我想到的前两个解决方案

更新 下面是使用内环
应用于代码的移位方法:\uu Test

@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
@echo关闭
setlocal EnableDelayedExpansion
调用:测试标题“这是第1行”、“这是第2行”arg3
端部
退出/b0
:测试
设置“i=0”
:u测试
设置/a“i+=1”
设置“val[!i!]=%2”
设置“tempvar=%4”
如果定义了tempvar shift/2和goto测试
设置“出发=”
对于/l%%n in(1,1,!i!)do(
出发=!出发!!瓦尔[%%n]!^&vbcrlf^&)
回显%1!输出:~1,-12!%3.
退出/b0

对于一般解决方案,通过引用传递值(将值存储在变量中并传递变量名称)是最佳选择。这与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。

谢谢David。SHIFT选项似乎是可行的,但我不知道如何在我的代码中实现它。@MattWilliamson我用一个例子更新了我的答案。@dbenham更新的例子有助于澄清方法1吗?我重视你的输入dbenham,因为你是批处理文件的专家。好的,我想我理解这个概念。请注意,这不能用于多个列表参数。我建议通过重新排列来简化问题g参数。我会把列表放在最后,这样3开始的所有参数都在列表中,并按照您的建议使用SHIFT循环。我现在明白了。我正在尝试在for循环中进行SHIFT。谢谢David!+1很好的解释和见解。也谢谢您对我的答案的输入。
One
"Two","Three"
Four
@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
@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