Кавычки.
Еще раз напомним, что если строка заключена в кавычки, то они являются частью строковой переменной.
И, поскольку они не являются цифрами, перед арифметической обработкой их желательно удалять.
Особенно в свете того, что команды
приведут вас к совершенно разному результату.
Системы счисления.
Если вы решили проверить работу двух предыдущих примеров, то, возможно, результаты вас удивили.
Дело в том, что символьные строки, содержащие числа и начинающиеся с нуля в команде
SET
с параметром /A считаются восьмеричными.
Результат будет 16, а не 18!
А команды
set /a s=08
set /a z=09
и вовсе приведут к ошибке, так как в восьмеричной системе счисления нет цифр 8 и 9.
Такие ситуации могут случаться в первую очередь при обработке даты, времени,
когда извлекается часть строки, содержащая, например, часы,
а затем с этими данными выполняются математические операции
И, естественно, при отладке это не обязательно проявится.
В разделе Работа с датой, временем. Примеры bat / cmd файлов так же
обращено внимание на эту проблему.
Как избежать описанных ошибок.
Если в силу каких-либо причин строковые данные заключены в кавычки,
их желательно удалить. Сделать это можно, например, так:
Следует отметить, что приведенный выше пример удаляет из строки первый и последний символ
(если их там столько есть).
Независимо от того, какие они.
Тут немного сложнее.
Очевидное решение – проверять является ли ведущий символ нулем и, если так, удалять его.
Если мы имеем дело с двухзначными данными ( а чаще всего это именно так – обработка даты, времени ),
то такой подход возможно уместен. В противном случае процесс итеративный.
Отличительная черта такого подхода – универсальность.
В то же время достаточно часто известно,
что обрабатываемая строка содержит фиксированное количество знаков,
например, 3 символа. В таком случае можно воспользоваться следующим приемом:
set /a s=”1%dd% % 1000″
В приведенном примере к трехзначному числу слева приписывается 1.
(Хотя для этого примера это с таким же успехом может быть другая цифра, кроме нуля)
Теперь для обработчика число начинается с 1 и, следовательно, является десятичным.
А теперь от этой искусственной добавки необходимо избавиться.
В данном примере берется остаток от деления на 1000.
А можно эту добавку и просто отнять
set /a s=1%dd% – 1000
Если данные содержат два символа, то пример буде выглядеть так:
Ну и для наглядности, если переменная dd была равна, скажем, 09,
то после подстановки пример будет выглядеть так:
set /a s=109 – 100
Таким образом можно безопасно и правильно получить цифровое значение,
записанное в символьном виде.
Зачастую после арифметической обработки данных возникает обратная задача –
сформировать строку определенной длины, содержащую требуемое число с необходимым количеством ведущих нулей.
Это более понятно на простом жизненном примере.
Рассмотрим следующую реальную задачу: в папке хранятся архивы, часть имени которых ( 4 знака )
являются порядковым номером архива. Необходимо сформировать имя следующего по порядку архива.
Здесь мы рассмотрим часть кода, где к максимальному номеру
(в символьном виде) прибавляется единица и
из него формируется строка из 4 символов с необходимым количеством ведущих нулей.
set /A DIG=1%SDIG% +1
set SNR=%DIG:~-4%
Для вычисления следующего номера мы используем тот же прием – приписываем слева единицу.
Далее из символьного представления увеличенного числа извлекаем 4 правых знака.
Ведущие нули там уже присутствуют в необходимом количестве.
Для большей наглядности рассмотрим это на примере.
Если переменная SDIG имела значение, например, 0008, то после подстановки
пример будет выглядеть так:
set /A DIG=10008 +1
set SNR=%10009:~-4%
Т. е. переменная SNR получит значение 0009.
Следует отметить, что при таком подходе чисто теоретически, после 9999 последует 0000.
И, если постановка задачи предусматривает иные действия при достижении максимально возможного значения,
ситуацию необходимо контролировать.
Надеюсь, что приведенный выше материал позволит вам избежать некоторых ошибок программирования,
а так же (набившее оскомину замечание) –
вдумчивее подойти к выбору языка программирования для решения конкретной задачи.
Для вопросов, обсуждений, замечаний, предложений и т. п. можете использовать
раздел форума
этого сайта (требуется регистрация).
Присвоить переменной значение пробел
set “charlist= “
Извлечение подстроки с конца строки
(часто этот прием используют для удаления окаймляющих кавычек)
Удаление подстроки в строке
В данном примере из строки будет удалена подстрока “кожа “
Удаление всех пробелов в строке
Как вариант предыдущего примера
Замена подстроки в строке
Глядя на этот пример не составит трудности написать процедуру
обратного преобразования.
——————————————————————————————————-
ЗАМЕНА ОДНОЙ ПОДСТРОКИ НА ДРУГУЮ В ФАЙЛЕ
Такую задачу можно решить без использования сторонних программ, только средствами bat !
Ниже приведен пример с использованием локальной процедуры txtrepl
Вывод на экран, в файл текста без перевода строки
Использование этого приема в сочетании с символом backspace (код 08)
позволяет сделать вывод на экран изменяемого текста и как вариант – “вращающейся палки”.
Вычисление длины строковой переменной
В bat/cmd командах нет функции, позволяющей вычислять длину строковой переменной.
А такая задача возникает не так уж и редко. Однако средств командного языка
достаточно, для того что бы решить такую задачу,
не прибегая к использованию специальных программ.
Рассмотрим несколько вариантов решения данной задачи:
:var_count2
set /a %2 =0
set var=%~1
:startvarcount
if not defined var exit /b
set var=%var:~1%
set /a %2+=1
goto startvarcount
exit /b
Еще один вариант вычисления длины строковой переменной:
:StringLen
:: ———————–
:: Нахождение длины строки
:: ———————–
:: %1 – текстовая строка
:: ———————–
Set $StringLen=0
Set $StringBuf=%~1
If “”==”%~1” GoTo :EOF
:StringLenLoop
Set /A $StringLen+=1
Call Set $StringChr=%%$StringBuf:~%$StringLen%%%
If “”==”%$StringChr%” GOTO :EOF
GoTo :StringLenLoop
Еще один способ определения длины строки, как ни странно – достаточно быстрый:
Ну и, наконец, решение, поразившее меня своей математической лаконичностью:
Для себя я так же использую метод половинного деления
для нахождения количества символов в строке.
Эта процедура менее изящна, и, возможно, потребует несколько большего времени
для вычислений, чем приведенная выше, но, на мой взгляд, она понятнее.
(В этом месте надо было похвалить себя еще, но что-то не нашлось достойных эпитетов)
Привожу на всякий случай и эту процедуру ))
Получение подстроки.
Если смещение начала подстроки и ее длина являются константами –
здесь все достаточно просто и аналогичный пример рассматривался выше:
Прошу прощения, если в качестве значения переменной str я опубликовал чей-то пароль )).
Если же одна или обе эти величины – переменные, то решение будет не столь простое.
Здесь встретиться возможно не совсем обычное применение команды CALL.
Немного глубже об этом на странице Полезное
в разделе Особенности использования команды CALL. Там же рассмотрен и этот пример.
Итак, рассмотрим возможные решения:
Или как вариант предыдущего
Удаление ведущих и замыкающих пробелов.
:ALLTRIM
:: ———————–
:: Krasner B.
:: ———————–
:: %1 – var with txt string
:: ———————–
SetLocal EnableDelayedExpansion
set /a firstnoblank=-1
set /a lastnoblank=0
set /a curpos=1
set “str=Q!%1!”
:StringLenLoop
set SUBD=!str:~%curpos%,1!
if “!SUBD!” == “” GoTo :formrez
if NOT “!SUBD!” == ” ” (
if !firstnoblank! == -1 set firstnoblank=!curpos!
set lastnoblank=!curpos!
)
set /a curpos = !curpos!+1
GoTo :StringLenLoop
:formrez
set /a n1=!firstnoblank!-1
set /a n2=!lastnoblank!-!firstnoblank!+1
if !firstnoblank! == -1 (set “rez=”) else (set rez=!%1:~%n1%,%n2%!)
ENDLOCAL & SET %~1=%rez%
exit /b 0
)
Глядя на этот пример не составит трудности написать процедуру
обратного преобразования.
——————————————————————————————————-
Такую задачу можно решить без использования сторонних программ, только средствами bat !
Ниже приведен пример с использованием локальной процедуры txtrepl
Использование этого приема в сочетании с символом backspace (код 08)
позволяет сделать вывод на экран изменяемого текста и как вариант – “вращающейся палки”.
В bat/cmd командах нет функции, позволяющей вычислять длину строковой переменной.
А такая задача возникает не так уж и редко. Однако средств командного языка
достаточно, для того что бы решить такую задачу,
не прибегая к использованию специальных программ.
Рассмотрим несколько вариантов решения данной задачи:
:StringLen
:: ———————–
:: Нахождение длины строки
:: ———————–
:: %1 – текстовая строка
:: ———————–
Set $StringLen=0
Set $StringBuf=%~1
If “”==”%~1” GoTo :EOF
:StringLenLoop
Set /A $StringLen+=1
Call Set $StringChr=%%$StringBuf:~%$StringLen%%%
If “”==”%$StringChr%” GOTO :EOF
GoTo :StringLenLoop
Для себя я так же использую метод половинного деления
для нахождения количества символов в строке.
Эта процедура менее изящна, и, возможно, потребует несколько большего времени
для вычислений, чем приведенная выше, но, на мой взгляд, она понятнее.
(В этом месте надо было похвалить себя еще, но что-то не нашлось достойных эпитетов)
Привожу на всякий случай и эту процедуру ))
Если смещение начала подстроки и ее длина являются константами –
здесь все достаточно просто и аналогичный пример рассматривался выше:
Прошу прощения, если в качестве значения переменной str я опубликовал чей-то пароль )).
Если же одна или обе эти величины – переменные, то решение будет не столь простое.
Здесь встретиться возможно не совсем обычное применение команды CALL.
Немного глубже об этом на странице Полезное
в разделе Особенности использования команды CALL. Там же рассмотрен и этот пример.
Итак, рассмотрим возможные решения:
:ALLTRIM
:: ———————–
:: Krasner B.
:: ———————–
:: %1 – var with txt string
:: ———————–
SetLocal EnableDelayedExpansion
set /a firstnoblank=-1
set /a lastnoblank=0
set /a curpos=1
set “str=Q!%1!”
:StringLenLoop
set SUBD=!str:~%curpos%,1!
if “!SUBD!” == “” GoTo :formrez
if NOT “!SUBD!” == ” ” (
if !firstnoblank! == -1 set firstnoblank=!curpos!
set lastnoblank=!curpos!
)
set /a curpos = !curpos!+1
GoTo :StringLenLoop
:formrez
set /a n1=!firstnoblank!-1
set /a n2=!lastnoblank!-!firstnoblank!+1
if !firstnoblank! == -1 (set “rez=”) else (set rez=!%1:~%n1%,%n2%!)
ENDLOCAL & SET %~1=%rez%
exit /b 0
)
Новый раздел о средствах командной строки в рамках этого же проекта расположен
здесь



