2016-10-16 1 views
4

ちょっと私はコーディングでかなり新しいです。^^!を使用して感嘆符をエスケープできるようです。私はsetlocal disabledelayedexpansionを使用するか、endlocalを使用する必要があることを知っていますが、エラーが出ることなく適切な場所を見つけることができません。ここで感嘆符をバッチファイルでエスケープすることはできません

cmdウィンドウの水平方向の中心にテキストを表示しようとする私のスクリプトです:

@echo off 
setlocal enabledelayedexpansion 
title Center Text 
mode 80,50 

set "cmdwidth=80" 
:Display 
cls 
set Center=This is a test^^! & call :CenterText Center strLen 
echo. 
pause 
exit 

:CenterText 
    if not "!%1:~%len%!"=="" set /A len+=1 & goto :CenterText 
(endlocal & set %2=%len%) 

goto CenterTextDisplay 
:AddSpace 
set "spaces=%spaces% " 
goto :eof 
:CenterTextDisplay 
set /a "indent=(cmdwidth - strLen)/2" 
set "spaces= " 
for /l %%a in (1,1,%indent%) do call :AddSpace 
echo %spaces%%Center% 
set "len=0" 
goto :eof 

これはエラーなしで私のコードですが、私は適切に感嘆符をエスケープすることはできません、その結果が代わりにThis is a testですThis is a test!です。

+2

あなたは 'delayedexpansion'を必要としない - 'を変更する ''% ''にして:私は 'を変更したときcentertext'とバッチファイル@Magoo' endlocal' – Magoo

+0

を失うことは実行されません! '%'にすると、ちょうどクラッシュする – VanZuron

+0

@Magoo、ネストされた展開( '!%1!')のため遅延拡張が実際に必要です... – aschipfl

答えて

2

感嘆符は、遅延拡張が有効になるたびに、リテラル文字列に感嘆符が含まれている場合、およびその文字列に感嘆符を含む変数がすぐに展開された場合(通常は%拡張)に失われます値;遅延拡張が起こる前にすべてが拡張されているので、forパラメータ(例えば、%%I)および引数参照(例えば、%1)についても同じことが当てはまる。
このような問題を回避するには、遅延拡張は実際に必要なときにのみ有効にする必要があります。

コードでは、遅延拡張をグローバルに有効にします。変数Centerには実際にエスケープマークが付いていますが、%Center%の行がecho %spaces%%Center%になるとすぐに失われます。ここで

が適応スクリプトです:遅れ拡張問題の修正のほかに

@echo off 
setlocal DisableDelayedExpansion 
title Center Text 
mode 80,50 

set "cmdwidth=80" 
:Display 
cls 
set "Center=This is a test!" & call :CenterText Center strLen 
echo/ 
pause 
endlocal 
exit /B 

:CenterText 
setlocal EnableDelayedExpansion 
:CenterText_Loop 
if not "!%~1:~%len%!"=="" set /A len+=1 & goto :CenterText_Loop 
endlocal & set "%~2=%len%" 
set /a "indent=(cmdwidth-strLen)/2" 
set "spaces= " 
for /l %%a in (1,1,%indent%) do call :AddSpace 
echo(%spaces%%Center% 
set "len=0" 
goto :eof 

:AddSpace 
set "spaces=%spaces% " 
goto :eof 

、私はまた、次のものを固定:

  • は、バッチスクリプトを終了するだけにexit /Bexitを変えたが、親ではないcmdインスタンス。
  • echo.echo/が変更されました。これは、現在のディレクトリにecho(ファイル名拡張子なし)というファイルが存在する場合に失敗する可能性があるためです。
  • set構文を改良して、一貫して代入式全体を引用します。
  • %1から%~1および%2から%~2に変更して、拡張された値から周囲の引用符を削除してください。
  • 移動フローを明確にし、ラベル:CenterTextDisplayと関連するgotoの必要性を避けるために、移動したサブルーチン:AddSpaceを下に移動します。これが遅延拡張の代替を示し

    for /l %%a in (1,1,%indent%) do call set "spaces=%%spaces%% " 
    

    :あなたは、このことにより、コマンドラインfor /l %%a in (1,1,%indent%) do call :AddSpaceを交換する場合
    は実際にあなたもそのサブルーチンを削除することができ、変数の周り%兆候を倍増し、callを使用して、しかし、一部の文字がまだ問題を引き起こす可能性があり、一部のコマンド(forおよびifなど)をcallで実行できないため、これはすべての状況で機能しません。

関連する問題