Если я полностью понимаю проблему, которую вы описываете в своем посте, и ваш comment, похоже, что вы не совсем понимаете свой код. Я попытаюсь объяснить, почему некоторые места в вашем скрипте никогда не будут доступны интерпретатором cmd. В результате код в этих местах никогда не будет выполнен.
Давайте рассмотрим первую часть кода (где начинается CMD переводчик):
@echo off
:: Ghost typer
setlocal enableextensions enabledelayedexpansion
set lines=6
set "line1=Twinkle twinkle little star"
set "line2=How I wonder what you are"
set "line3=Up above the world so high"
set "line4=Like a diamond in the sky"
set "line5=Twinkle twinkle little star"
set "line6=How I wonder what you are"
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"
for /L %%a in (1,1,%lines%) do set num=0&set "line=!line%%a!"&call :type
pause>nul
goto :EOF
отключить печать каждой команды с @echo off
, включите delayed expansion, установите все ваши переменные, содержащие каждую линию вашего текст, используйте цикл for /f
, чтобы получить символ обратного пробела, который будет использоваться во время ввода текста (я не совсем понимаю, почему команда prompt
используется для циклических и двойных кавычек) и использовать цикл for /L
для итерации над всеми вашими lines
и напечатайте их с call доФункцияреализована во второй части вашего скрипта. После этого pause>nul
заставит консоль ждать, пока пользователь не нажмет на клавишу. И, наконец, goto :EOF
используется для прекращения выполнения текущего пакетного скрипта (или «context», см. Далее), иначе cmd-интерпретатор продолжил бы и выполнял бы код под подпрограммой :type
дополнительное время (что, скорее всего, не ваше намерение). Как поясняется в Microsoft's documentation for the goto
command, :EOF
является предопределенной меткой, которая может использоваться для выхода из текущего пакетного скрипта. Итак, все, что вы ставите под goto :EOF
, никогда не будет выполнено или, по крайней мере, не в том же «контексте» (см. Далее, чтобы понять, что означает «тот же контекст»).
Но тогда, как получается, выполняется подпрограмма :type
, а goto :EOF
не выходит из вашего командного сценария?
:type
set "letter=!line:~%num%,1!"
set "delay=%random%%random%%random%%random%%random%%random%%random%"
set "delay=%delay:~-6%"
if not "%letter%"=="" set /p "=a%bs%%letter%" <nul
:: adjust the 3 in the line below: higher is faster typing speed
for /L %%b in (1,3,%delay%) do rem
if "%letter%"=="" echo.&goto :EOF
set /a num+=1
goto :type
Это благодаря команде call
. :type
- это всего лишь ярлык, как и другие, но причина, почему я называю это подпрограммой, заключается в том, что вы используете call
, а не goto
, чтобы выполнить то, что находится под ним. A goto
просто перескочит на ярлык, который вы ему дали, и забудьте о том, что он делал до goto
. С другой стороны, команда call
создаст новый контекст поверх контекста, в котором выполняется скрипт.Таким образом, можно вернуться к тому, где выполнение сценария остановилось до call
, когда новый контекст закрыт и вышел (немного напоминает вызов и возврат из подпрограммы). Чтобы выйти из этого контекста, cmd-парсер должен столкнуться с обычным файлом (скриптом), явной командой exit
или, как в этом случае, goto :EOF
. НО даже в контексте подпрограммы :type
код ниже goto :type
не будет выполнен. Действительно, после for /L
под :type
этикетке есть 2 случая:
- либо
%letter%
пуст: в этом случае пустая строка будет напечатана (echo.
) и контекст будет закрыт из-за goto :EOF
. Это означает, что восходит к контексту сценария (где он будет продолжать с for /L
Перебором текста)
- или
%letter%
не пусто: переменная num
затем увеличивается и CMD интерпретатор переходит обратно к :type
этикетке (потому что goto :type
) без кода goto :type
(получить разницу между goto
и call
? в случае call
он выполнил бы код под ним в определенный момент).
Теперь я могу показать вам место, где вы можете добавить код, который должен быть выполнен, и место, где код не будет выполняться на всех кроме если поместить метку в тех местах и использовать goto
или call
(остерегайтесь различий и опасностей) на эту метку в областях, где вы можете добавить код. Я также изменил for /L
и if
, где вы используете &
. &
s сделает ваш код немного более нечитаемым. В вашем случае они действительно не нужны, поэтому я поместил каждую команду в свою линию и приложил команды с помощью (...)
.
@echo off
:: Ghost typer
setlocal enableextensions enabledelayedexpansion
set lines=6
set "line1=Twinkle twinkle little star"
set "line2=How I wonder what you are"
set "line3=Up above the world so high"
set "line4=Like a diamond in the sky"
set "line5=Twinkle twinkle little star"
set "line6=How I wonder what you are"
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"
REM Here is place OK 1
REM Gets executed before the text prints
for /L %%a in (1,1,%lines%) do (
set num=0
set "line=!line%%a!"
call :type
)
REM Here is place OK 2
REM Gets executed after the text prints
pause>nul
goto :EOF
! THIS PART IS NEVER REACHED BY THE CMD-INTERPRETER !
:type
set "letter=!line:~%num%,1!"
set "delay=%random%%random%%random%%random%%random%%random%%random%"
set "delay=%delay:~-6%"
if not "%letter%"=="" set /p "=a%bs%%letter%" <nul
:: adjust the 3 in the line below: higher is faster typing speed
for /L %%b in (1,3,%delay%) do rem
if "%letter%"=="" (
echo.
REM Place OK 3
REM Here can come code that gets executed after each line is printed
goto :EOF
)
set /a num+=1
goto :type
! THIS PLACE WILL NEVER BE REACHED BY THE CMD-INTERPRETER EITHER !
Я надеюсь, что это длинное сообщение помогло. Не стесняйтесь задавать вопросы, если у вас есть.
Удачи вам!
Где мой код? Вставьте его в свой вопрос, чтобы мы могли помочь. – byxor
K Я добавил бит кода, который я пытался манипулировать сообщением, извините. – Dubby
этот код работает нормально. Где эта часть, у вас проблемы? – Stephan