1 (изменено: wisgest, 2012-09-28 12:02:26)

Тема: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

Я не понял зачем было добавлять этот банный стыд в Коллекцию.

(Несколько несущественных замечаний, не относящихся к моему искреннему недоумению:
в конце строки 5 между «=» и «)» лучше убрать пробел — он является значащим и попадает в приглашение на ввод;
отсутствует проверка на ввод пустой строки;
обрабатывается только первая строка файла при перенаправлении, а приведённый в конце пример «шан ечто» состоит из трёх строк;

то же самое делается короче:

@echo off
SETLOCAL EnableExtensions EnableDelayedExpansion
set text=%*
if _!text!==_ set /p text=
if _!text!==_ exit /b

set /a i=0
:LOOP
if _!text:~%i%^,1!==_ echo,& exit /b
set /a i+=1
<nul set /p novar="!text:~-%i%,1!"
goto LOOP

).

[OFF]
По поводу строки в моём решении

if _!text:~%i%^,1!==_ …

у меня возник вопрос: почему понадобилось экранировать запятую?!

В соблюдение п.3.11 Правил перенёс обсуждение запятой в условии IF в отдельную тему.
[/OFF]

2

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

Ну зачем же ругаться и метать молнии?
вентиляторов вроде нет...

Скрипт - объединение функций strLen() и reverseStr(), только и всего.
Да, обрабатывает одностроченый файлы.
Для полноты ритуала можно сохранить целостность текста и переворачивать только слова.
Но, думаю, что для академической выкладки превыше краткость и простота.

Касательно же экранирования запятой в вашем решении, то пока я не смогу вам ответить, почему понадобилось это делать.

3

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

:

@echo off
setlocal enableextensions enabledelayedexpansion

call :Reverse "Мама мыла раму"

echo [%Reverse%]

endlocal
exit /b 0

:Reverse
    setlocal enableextensions enabledelayedexpansion
    set sOutName=%~0
    
    set sValue=%~1
    
    if defined sValue (
        call :Reverse "%sValue:~1%"
        set sResult=!Reverse!%sValue:~0,1%
    )
    
    endlocal & set %sOutName:~1%=%sResult%
    exit /b

4

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

[OFF]На всякий случай заранее извинюсь перед всеми уважаемыми собеседниками за обращение в единственном числе — с моей стороны это не является проявлением неуважения, скорее наоборот, но если кому-то неприятно, могу и исправится. Не распространяясь более здесь по этому вопросу, лишь напомню, что именно к этому призывал когда-то отец-основатель этого форума.[/OFF]


Аскет, извини за возможную грубость моего исходного сообщения и спасибо за спокойный, взвешенный ответ.
Попытаюсь развернуть свою мысль. На мой взгляд в Коллекцию должны добавляться решения удовлетворяющие одному из условий:
1) практически полезные,
2) теоретически/академически интересные,
3) неожиданные.
Твоя же тема напоминает унылые искусственные задачи из задачников по программированию (вроде подсчитать, сколько раз в строке встречается буква «a») с предсказуемо тривиальным решением, к тому же несколько небрежно оформленная.

Спасти положение, впрочем, можно, сместив акцент в изложении в том направлении, которое ты сам и указал:

Аскет пишет:

Скрипт - объединение функций strLen() и reverseStr()

В CMD действительно не хватает встроенных средств обработки строк, в первую очередь — определения длины строки, и законченное решение этого вопроса вполне можно поместить в Коллекцию.

Заодно можно было бы, обозвав тему как-то наподобие «CMD/BAT: Пользовательские стороковые функции», добавить в неё и reverseStr(),
коль уж в VBScript есть функция StrReverse();
а в JavaScript массивы имеют метод reverse()), с помощью которого легко переворачивать и строки:

"qwerty".split("").reverse().join("");

) и в качестве примера использования этих функций дать приблизительно тот код, который был дан изначально.

Но функция backstrF в том виде, что сейчас, не годится; в самом деле, что она делает: возвращает перевёрнутую строку или сразу печатает результат?

5

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

Немного переименовал тему.


На форуме ранее поднималась тема «CMD/BAT: Получение длины текстовой строки» (удалена; в Script-Coding-Community.chm/web/viewtopic9a22.html).
Для полноты картины воспроизвожу её здесь:

2009-08-04 03:26:59 (отредактировано 2009-08-05 16:08:43):

kiber_punk пишет:

На форуме,вроде как, нету.
Возникла необходимость вычисления длины строковой переменной, нашлись удобные решения проблемы:

@Echo Off
Call :StrLen "%*"
Echo %StringLen%

:StrLen
:: -----------------------
:: Нахождение длины строки
:: %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

Ещё вариант, достаточно необычное решение:

@Echo Off
Set a=%*

Echo.%a%>"%temp%\%~n0.tmp"
For %%i In ("%temp%\%~n0.tmp") Do Set /A z=%%~zi-2

Echo %z%

Источник

2009-08-04 16:59:59

Rumata пишет:

Хотя второй вариант и требует создания временного файла, он лучше, так как его скорость ограничена лишь скоростью дисковых операций чтения/записи/доступа.

2009-08-04 18:41:07:

alexii пишет:

Да, но он (как, впрочем, и первый вариант) не всегда соответствует истине. Также желательно позаботиться об удалении временного файла.

2010-01-23 15:10:16 (отредактировано 2010-01-24 13:12:27):

Rumata пишет:

По мотивам этого сообщения модифицировал вариант с временным файлом. Длина строки точно соответствует размеру файла и учтено предыдущее замечание alexii:

:: применение
:: call :str_len NAME [STRING]
:: NAME   - имя переменной для сохранения значения
:: STRING - строка, длину которой надо вычислить
:str_len
if "%~2" == "" (
    set %~1=0
    goto :EOF
)

(set /p %~1=%~2)<nul>"%TEMP%\%~n0.txt"

for /f %%a in ( "%TEMP%\%~n0.txt" ) do (
    set %~1=%%~za
    del "%%a" 2>nul
)
goto :EOF

Дополнение: На форуме уже описан этот способ CMD/BAT: вывод текста без переноса на новую строку.

6

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

alexii, спасибо, #3 — интересное, может быть, даже красивое решение (с небольшим изменением его можно переделать и в функцию для подсчёта длинны строки), но на мой взгляд, — несколько неэффективное (рекурсия + setlocal, создающая полную копию всех переменных окружения)…

7

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

wisgest, ага . В оригинале это была иллюстрация на тему, что, дескать, и в командном процессоре можно использовать рекурсию. Собственно обращение строки была «притянута» туда только как наглядная иллюстрация.

8

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

alexii пишет:

в командном процессоре можно использовать рекурсию

Можно, ради "академичности" вопроса рассмотреть такие алгоритмы (показаны результаты на каждом шагу исполнения).

первый: предварительно надо вычислить длину строки

1 2 3 4 5 6
4 5 6 1 2 3
6 5 4 1 2 3
6 5 4 3 2 1

второй: знания длины строки не требуется, алгоритм завершается после пересечения середины

1 2 3 4 5 6
6 2 3 4 5 1
6 5 3 4 2 1
6 5 4 3 2 1

( 2 * b ) || ! ( 2 * b )

9

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

wisgest пишет:

Аскет, извини за возможную грубость моего исходного сообщения и спасибо за спокойный, взвешенный ответ.
Попытаюсь развернуть свою мысль. На мой взгляд в Коллекцию должны добавляться решения удовлетворяющие одному из условий:
1) практически полезные,
2) теоретически/академически интересные,
3) неожиданные.

А ведь когда-то и я призывал к этой и даже более жёсткой дисциплине. ))

Твоя же тема напоминает унылые искусственные задачи из задачников по программированию (вроде подсчитать, сколько раз в строке встречается буква «a») с предсказуемо тривиальным решением, к тому же несколько небрежно оформленная.

А вот мне показалось что тема «ни разу не обсосона» и в самый раз для Коллекции. И ничего она не небрежно, а отнюдь даже аккуратно и стиллистично. )

Твоя же тема напоминает унылые искусственные задачи из задачников по программированию

...Не распространяясь более здесь по этому вопросу, лишь напомню, что именно к этому призывал когда-то отец-основатель этого форума:

The gray Cardinal пишет:

Моё мнение: любой "Hello World" в Коллекции полезен.

В приходящем в упадок обществе, подлинное искусство должно отражать это разложение.   /Эрнст Фишер/
:)

10

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

Rumata пишет:

второй: знания длины строки не требуется, алгоритм завершается после пересечения середины

Rumata, а как будет определяться середина строки?

11

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

wisgest пишет:

В CMD действительно не хватает встроенных средств обработки строк, в первую очередь — определения длины строки, и законченное решение этого вопроса вполне можно поместить в Коллекцию.

Заодно можно было бы, обозвав тему как-то наподобие «CMD/BAT: Пользовательские стороковые функции», …

У меня такая мысль была, тем более, что функция теперь действительно почти что функция.

12

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

alexii пишет:

а как будет определяться середина строки?

Виноват. Длину строки все-таки знать надо.

( 2 * b ) || ! ( 2 * b )

13

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

Аскет пишет:

Не распространяясь более здесь по этому вопросу, лишь напомню, что именно к этому призывал когда-то отец-основатель этого форума:

Ссылка на мнение авторитета — лишь средство сокращения рассуждений, но не окончательная истина.
Я прибег к ней, чтобы не отклоняться от темы, ты — чтобы уйти от ответа.
(

wisgest пишет:

могу и исправится

)

Аскет пишет:
The gray Cardinal пишет:

Моё мнение: любой "Hello World" в Коллекции полезен.

— вырвано из контекста:

The gray Cardinal пишет:

Языки разные. И когда вы полезете осваивать новый для себя язык,

Конечно, если поместить в Коллекцию сообщение о каком-нибудь FortranScript'е, то можно на худой конец в качестве примера дать и «Hello World». То же самое, и даже в большей степени, можно сказать о различных способах вывода информации (всплывающие подсказки, голосовые сообщения…) или выводе из одного языка или технологии средствами друго(го/й).

Аскет пишет:

А вот мне показалось что тема «ни разу не обсосона» и в самый раз для Коллекции.

Концептуально — это пример посимвольной обработки строки, а такие вещи, по-моему, были.
Поэтому требуется внятное объяснение нужности этого частного случая, не то таких «необсосаных» примеров «JUST FOR LULZ» можно наплодить сколько угодно (удвоение каждого символа, перестановка соседних четных и нечётных символов…).



Аскет пишет:

И ничего она не небрежно

Повторю и добавлю.

wisgest пишет:

в конце строки 5 между «=» и «)» лучше убрать пробел — он является значащим и попадает в приглашение на ввод;

Входная и выходная строки по идее имеют одинаковую длинну и выглядит небрежно, что они располагаются не одна под одной, а со сдвигом. Или надо полноценное приглашение на ввод.

wisgest пишет:

отсутствует проверка на ввод пустой строки;

При вводе пустой строки в выходной поток попадает:

~,1

а в поток сообщений об ошибках:

Ошибка в синтаксисе команды.

Если же входная строка, содержит кавычки, то либо строка обрабатывается не полностью, либо возникают сообщения об ошибках, причём многократные и иногда различающиеся между собой.
Можно по этому поводу не править код, но в таком случае в описании обязательно должно быть сказано об ограничениях на входные данные!
(Для сравнения, мой пример из #1 переворачивал строку с кавычками, но кавычки выбрасывал. Впрочем я это легко исправил: в строке

<nul set /p novar=!text:~-%i%,1!

«приглашение на ввод» взял в кавычки — как видим, в команде set /p можно заключать приглашение во внешние кавычки (например, если оно содержит спецсимволы), которые при выводе приглашения отбрасываются.)

wisgest пишет:

обрабатывается только первая строка файла при перенаправлении, а приведённый в конце пример «шан ечто» состоит из трёх строк;

Аскет пишет:

Да, обрабатывает одностроченый файлы.

Так зачем трёхстрочный пример (и нужен ли он вообще)? — Однозначно небрежность.
Название темы.
Что такое «перевёртыш»: двуличный человек, фантастическое существо, детская забава со словами («две попы — плохо, одна попа — совсем беда»)?..
Как видим Аскет сам понял, что этого слова не достаточно и добавил пояснение «зеркальное обращение текста». Но, во-первых, зачем тогда было оставлять «перевёртыша»? а, во-вторых, это не намного понятней: я, например, подумал, что Аскет умудрился выводить в консоли средствами командных файлов текст в действительно зеркально отражённом виде.

Аскет пишет:

Скрипт - объединение функций strLen() и reverseStr(), только и всего.

Это не отражено ни в названии, ни в описании. Если я буду искать в Коллекции функцию strLen(), то, скорее всего не догадаюсь, что она спрятана в этой теме; функции reverseStr() вообще не вижу:

wisgest пишет:

Но функция backstrF в том виде, что сейчас, не годится; в самом деле, что она делает: возвращает перевёрнутую строку или сразу печатает результат?

__


Аскет пишет:

А ведь когда-то и я призывал к этой и даже более жёсткой дисциплине.

Теперь понятно, что значит «перевёртыш»!

14 (изменено: wisgest, 2012-09-28 14:11:17)

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

alexii пишет:

а как будет определяться середина строки?

А как определяяется второй край строки при рекурсивной обработке начиная с края?
Не вижу принципиальных отличий, как впрочем и преимуществ.

Если %s% — обрабатываемая строка на текущем шаге рекурсии, то
%s:~0,1% — её первый символ,
%s:~-1,1% или просто %s:~-1% — последний символ,
%s:1,-1% — средняя часть, обрабатываемая на следующем шаге,
и условием прекращения рекурсии является то, что строка пустая или односимвольная, т.е. совпадает со своим крайним символом.

15

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

wisgest пишет:

Не вижу принципиальных отличий, как впрочем и преимуществ.

Впрочем, при вызовах SETLOCAL при рекурсии таких вызовов будет в два раза меньше.

16

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

wisgest, как будет выглядеть код?

17

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

alexii пишет:

wisgest, как будет выглядеть код?

@echo off
setlocal enableextensions enabledelayedexpansion

call :Reverse "Мама мыла раму"
echo [%Reverse%]

call :Reverse "Мама мыла раму?"
echo [%Reverse%]

endlocal
exit /b 0

:Reverse
    setlocal enableextensions enabledelayedexpansion
    set sOutName=%~0
    
    set sValue=%~1
    
    if defined sValue if not "!sValue:~0,1!"=="!sValue!" (
        call :Reverse "%sValue:~1,-1%"
        set sValue=%sValue:~-1%!Reverse!%sValue:~0,1%
    )
    
    endlocal & set %sOutName:~1%=%sValue%
    exit /b

18

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

ничего не понял

@echo off

set x=а мама мыла раму
:rev
set y=%y%%x:~-1%
set x=%x:~,-1%
if defined x goto rev
echo %y%
Я конечно далек от мысли... (с)

19

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

wisgest пишет:

Ссылка на мнение авторитета — лишь средство сокращения рассуждений, но не окончательная истина.

Дадада, именно, тут вы совершенно правы. Ведь как однажды заметил выдающийся египтолог Джеральд Месси:
Им будет непросто, тем кто полагается на истину авторитета, вместо того, чтобы полагаться на авторитет истины.

wisgest пишет:

Я прибег к ней, чтобы не отклоняться от темы, ты — чтобы уйти от ответа.

Ненене, только для того чтобы показать некоторую несостоятельность Тваших утверждений.
__

wisgest пишет:
Аскет пишет:

Да, обрабатывает одностроченый файлы.

Так зачем трёхстрочный пример (и нужен ли он вообще)? — Однозначно небрежность.

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

20

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

smaharbA пишет:

ничего не понял

В #17? — Это изощрения JUST FOR LULZ на тему рекурсии:
см. #3—#6—#7—#8—#10—#14—#15—#16—#17.

Спасибо за пример кода дополнительно подтверждающий несостоятельность для Коллекции обсуждаемой темы в её нынешних постановке вопроса и исполнении.

21

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

вы бы лучче объяснили таковое

for /l %%x in (0,1,50) do (
    echo %%x
    if %%x gtr 20 goto m1
)
:m1
setlocal enabledelayedexpansion
set /a n=0
for /l %%x in () do (
    echo !n!
    set /a n+=1
    if !n! gtr 20 goto m2
rem для пущей зпущенности вместо гото можете попробовать exit /b
)
:m2
Я конечно далек от мысли... (с)

22

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

smaharbA пишет:

вы бы лучче объяснили таковое

Как это относится к теме?
В первом цикле, по-моему, нечего объяснять,
во-втором заинтересовала запись диапазона для вечного цикла

for /l %%x in () do (

не не более того.

23

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

а Вы выполнили код ?

Я конечно далек от мысли... (с)

24

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

Хотя я не прав, действительно, есть что обсуждать!!
Только связи с этой темой всё равно не замечаю.

25

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

smaharbA пишет:

объяснили таковое

wisgest пишет:

Только связи с этой темой всё равно не замечаю

Согласен.

smaharbA, создайте отдельную тему, где можно было бы поговорить по поводу магии в Вашем примере. Я запустил тот код, но ничего интересного не произошло. Завершить скрипт пришлось не просто нажатием CTRL+C, но еще и подтвердить свой отказ клавишей - "Y", что мне не нравится - ну сказал я CTRL+C, значит все - баста.

( 2 * b ) || ! ( 2 * b )

26

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

отдельная тема говорите

@echo off

setlocal ENABLEDELAYEDEXPANSION
set x=а мама мыла раму
for /l %%x in () do (
    <nul set /p y=!x:~-1!
    set x=!x:~,-1!
    if not defined x exit /b
)
Я конечно далек от мысли... (с)

27

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

Да, отдельная — о проблеме принудительного выхода из цикла!
В случае вечного цикла командный интерпретатор зависает, так что этот пример не очень полезен.
Для лучшего понимания можно включить режим вывода команд на экран (ECHO ON) и ограничится конечным циклом:

echo ON
prompt cmd$g

setlocal ENABLEDELAYEDEXPANSION
set x=а мама мыла раму
for /l %%x in (0,1,25) do (
    echo Следующая буква: !x:~-1!
    set x=!x:~,-1!
    if not defined x exit /b
)

28

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

с конечным циклом все предельно ясно, интерес составляет бесконечный
конечный

@echo off
setlocal ENABLEDELAYEDEXPANSION
set x=а мама мыла раму
call :length %x%
for /l %%x in (1,1,%length%) do (
    set y=!y!!x:~-%%x,1!
)
echo.!y!
exit /b

:length
setlocal ENABLEDELAYEDEXPANSION
set out=%~0
set opt= %*
:rev
if not "!opt:~%n%,1!"=="" set /a n+=1 & goto rev
endlocal && set /a %out:~1%=%n%-1
exit /b
Я конечно далек от мысли... (с)

29

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

smaharbA пишет:

с конечным циклом все предельно ясно, интерес составляет бесконечный

Если непонятно, я привёл пример в #27 с конечным циклом, нарочно взяв диапазон с избытком и включиd ECHO ON, чтобы показать, что полноценного принудительного выхода из цикла со счётчиком (FOR /L) по командам GOTO или EXIT /B не происходит: тело цикла перестаёт выполняться, но счётчик продолжает крутиться и лишь когда он достигнет предельного значения произойдёт выполнение команды, на которую передано управление GOTO, или выход по EXIT /B, чего в случае бесконечного цикла никогда не случится — поэтому он, на мой взгляд, и не представляет практического интереса.
По крайней мере так обстоит дело у меня — возможно в других версиях CMD.EXE эта проблема решена.

30

Re: CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции

Могли бы не расписывать - результат очевиден при конечном значении, но очевиден только по завершению итераций, что сути проблемы не меняет.
Бесконечный цикл был бы крайне полезен, в том числе и сабжевой теме.

Я конечно далек от мысли... (с)