Вопрос:

Неизвестная проблема при попытке печати подстроки в пакетном скрипте

batch-file

10 просмотра

1 ответ

6 Репутация автора

Итак, я пытался создать пакетный скрипт для автоматизации задачи в моей системе, для этого необходимо, чтобы я создал процедуру, которая позволит мне печатать строку по одному символу за раз, поэтому допустим, что моя строка равна «Hello» "(без кавычек), тогда ожидаемый результат:

>test.bat Hello
H
He
Hel
Hell
Hello

И это код, который я придумал:

@echo off
title test

set string=%1
set /A i=0

:print_str
setlocal enabledelayedexpansion
if "%string%"=="!string:~0,!i!!" (
    echo %string%
    endlocal
    goto eof
) else (
    echo !string:~0,!i!!
    set /A i+=1
    goto print_str
)

:eof
pause > nul

================================================== ======================

Что я думаю, это проблема:

После того, как я потратил некоторое время на тестирование и попытался выяснить, что может вызвать эту проблему, я обнаружил, что проблема в !string:~0,!i!!инструкции и что она не анализируется так, как я предполагал, я попробовал следующий код, чтобы получить лучшее представление о проблеме:

@echo off
title test1

set string=hello
set /A i=1

echo %string:~0,%i%%
pause > nul

и это был его вывод:

>test1.bat
%i

очевидно, это был не результат, который я ожидал, я ожидал подстроку 'e', ​​и именно так я пришел к выводу, что проблема в test.bat связана с инструкцией подстроки.

Я пробовал много вещей, таких как удвоение процентной отметки (думая, что это похоже на проблему% и %%), включая отложенные расширения, но безуспешно!

================================================== ======================

Минимальный код:

@echo off
title test

:print_str
setlocal enabledelayedexpansion

:eof
pause > nul

================================================== ======================

Алгоритм:

Способ, которым я намеревался заставить это работать, является следующим:

Мы инициализируем индекс (переменная i) равным 0, и на каждой итерации, если условие остановки не проверяется, мы печатаем текущую подстроку (она будет иметь такое же количество символов, что и текущее значение индекса), а затем мы увеличиваем индекс по одному, и мы повторяем процесс, ifоператор здесь, чтобы убедиться, что мы не превышаем длину строки, а также чтобы избежать бесконечного цикла, сравнивая полную строку с подстрокой строки, эта подстрока будет меняться каждый раз время индекс отличается и в конечном итоге будет равен строке после определенного количества итераций (когда я буду равен длине строки).

Проблема и вывод на консоль:

Однако это не сработало так, как я ожидал, когда я выполняю скрипт, я всегда оказываюсь в бесконечном цикле, который печатает следующие строки Максимальный достигнутый уровень рекурсии setlocal. i Максимальный заданный локальный уровень рекурсии достигнут. i Максимальный заданный локальный уровень рекурсии достигнут. я , , и так до тех пор, пока я не убью Иова, нажав Ctrl + C

Вопросы:

1) Можете ли вы объяснить мне, почему я получаю этот бесконечный цикл? и почему вывод !string:~0,!i!!только i 2) -Пожалуйста, объясните мне, как использовать команду echo с, !string:~0,!i!!когда длина не является постоянной

любые предложения по коду, мы будем глубоко признательны, заранее спасибо

Автор: HABILA Источник Размещён: 11.08.2019 04:26

Ответы (1)


0 плюса

62713 Репутация автора

Ваша фундаментальная проблема заключается в том, что "!string:~0,!i!!"интерпретируется как то, "!string:~0,!+i+!!"что никогда не будет равно "% string%", следовательно, elseчасть выполняется постоянно, отображая i.

Следующая проблема заключается в том, что setlocalэто не переключатель - он открывает фрейм, который закрывается endlocalили достигает конца файла. Количество этих кадров ограничено 32.

С вашим кодом операторы перед setlocalустановкой переменных будут постоянно в среде для этого экземпляра cmd. В результате пользовательские переменные загромождают среду. Следовательно, обычной практикой является использование команды a setlocalсразу после начальной @echo off.

Поскольку echo !string:~0,%i%!будет проанализировано, как и echoдолжно iбыть 0, то это заявление сообщит о echoстатусе, следовательно, iдолжно быть минимум 1.

Оператор goto :eof( :здесь требуется) определяется как переход к физическому концу файла. Объявление метки пользователя не :eofявляется стандартным и сбивает с толку тех, кто может поддерживать код.

Автор: Magoo Размещён: 11.08.2019 07:41
Вопросы из категории :
32x32