Цикл for отправка писем

Цикл for отправка писем thumbnail

Обновл. 15 Сен 2020 |

Безусловно, наиболее используемым циклом в языке C++ является цикл for.

Цикл for

Цикл for в языке С++ идеален, когда известно необходимое количество итераций. Выглядит он следующим образом:

for (объявление переменных; условие; инкремент/декремент счетчика)

тело цикла;

Или, преобразуя for в эквивалентный цикл while:

{ // обратите внимание, цикл находится в блоке

объявление переменных;

while (условие)

{

тело цикла;

инкремент/декремент счетчика;

}

} // переменные, объявленные внутри цикла, выходят из области видимости здесь

Переменные, определенные внутри цикла for, имеют специальный тип области видимости: область видимости цикла. Такие переменные существуют только внутри цикла и недоступны за его пределами.

Выполнение цикла for

Цикл for в C++ выполняется в 3 шага:

Шаг №1: Объявление переменных. Как правило, здесь выполняется определение и инициализация счетчиков цикла, а точнее – одного счетчика цикла. Эта часть выполняется только один раз, когда цикл выполняется впервые.

Шаг №2: Условие. Если оно равно false, то цикл немедленно завершает свое выполнение. Если же условие равно true, то выполняется тело цикла.

Шаг №3: Инкремент/декремент счетчика цикла. Переменная увеличивается или уменьшается на единицу. После этого цикл возвращается к шагу №2.

Рассмотрим пример цикла for и разберемся детально, как он работает:

#include <iostream>

int main()

{

for (int count = 0; count < 10; ++count)

std::cout << count << ” “;

return 0;

}

Сначала мы объявляем переменную count и присваиваем ей значение 0. Далее проверяется условие count < 10, а так как count равен 0, то условие 0 < 10 имеет значение true. Следовательно, выполняется тело цикла, в котором мы выводим в консоль переменную count (т.е. значение 0).

Затем выполняется выражение ++count, т.е. инкремент переменной. Затем цикл снова возвращается к проверке условия. Условие 1 < 10 имеет значение true, поэтому тело цикла выполняется опять. Выводится 1, а переменная count увеличивается уже до значения 2. Условие 2 < 10 является истинным, поэтому выводится 2, а count увеличивается до 3 и так далее.

В конце концов, count увеличивается до 10, а условие 10 < 10 является ложным, и цикл завершается. Следовательно, результат выполнения программы:

0 1 2 3 4 5 6 7 8 9

Циклы for могут быть несколько сложны для новичков, однако опытные кодеры любят их, так как эти циклы очень компактны и удобны. Для наглядности, давайте преобразуем цикл for, приведенный выше, в эквивалентный цикл while:

#include <iostream>

int main()

{

{ // внешние скобки нужны для обеспечения области видимости цикла

int count = 0;

while (count < 10)

{

std::cout << count << ” “;

++count;

}

}

return 0;

}

Обратите внимание, внешние фигурные скобки здесь необходимы, так как переменная count выходит из области видимости при завершении цикла.

Еще примеры циклов for

Давайте, используя цикл for, напишем функцию вычисления значений в степени n:

int pow(int base, int exponent)

{

int total = 1;

for (int count=0; count < exponent; ++count)

total *= base;

return total;

}

Функция возвращает значение base^exponent (число в степени n). base – это число, которое нужно возвести в степень, а exponent – это степень, в которую нужно возвести base.

Если экспонент равен 0, то цикл for выполняется 0 раз, и функция возвращает 1.

Если экспонент равен 1, то цикл for выполняется 1 раз, и функция возвращает 1 * base.

Если экспонент равен 2, то цикл for выполняется 2 раза, и функция возвращает 1 * base * base.

Хотя в большинстве циклов используется инкремент счетчика, мы также можем использовать и декремент счетчика:

#include <iostream>

int main()

{

for (int count = 8; count >= 0; –count)

std::cout << count << ” “;

return 0;

}

Результат:

8 7 6 5 4 3 2 1 0

Также с каждой новой итерацией мы можем увеличить или уменьшить значение счетчика больше, чем на единицу:

#include <iostream>

int main()

{

for (int count = 9; count >= 0; count -= 2)

std::cout << count << ” “;

return 0;

}

Результат:

9 7 5 3 1

Ошибка неучтенной единицы

Одна из самых больших проблем с которой приходится сталкиваться начинающим программистам в циклах for (а также и в других типах циклов) – это ошибка на единицу (или «ошибка неучтенной единицы»). Она возникает, когда цикл повторяется на 1 раз больше или на 1 раз меньше нужного количества итераций. Это обычно происходит из-за того, что в условии используется некорректный оператор сравнения (например, > вместо >= или наоборот). Как правило, эти ошибки трудно отследить, так как компилятор не будет жаловаться на них, программа будет работать, но её результаты будут неправильными.

При написании циклов for помните, что цикл будет выполняться до тех пор, пока условие является истинным. Рекомендуется тестировать циклы, используя разные значения для проверки работоспособности цикла. Хорошей практикой является проверять циклы с помощью данных ввода (чисел, символов и прочего), которые заставляют цикл выполниться 0, 1 и 2 раза. Если цикл работает исправно, значит всё ОК.

Правило: Тестируйте свои циклы, используя входные данные, которые заставляют цикл выполниться 0, 1 и 2 раза.

Пропущенные выражения в цикле

Также в циклах можно пропускать одно или сразу все выражения, например:

#include <iostream>

int main()

{

int count = 0;

for (; count < 10; )

{

std::cout << count << ” “;

++count;

}

return 0;

}

Результат:

0 1 2 3 4 5 6 7 8 9

Инициализацию счетчика мы прописали вне тела цикла, а инкремент счетчика – внутри тела цикла. В самом операторе for мы указали только условие. Иногда бывают случаи, когда не требуется объявлять счетчик цикла (потому что у нас он уже есть) или увеличивать его (так как мы увеличиваем его каким-то другим способом).

Хоть это и не часто можно наблюдать, но в операторе for можно вообще ничего не указывать. Стоит отметить, что подобное приведет к бесконечному циклу:

for (;;)

тело цикла;

Вышеприведенный пример эквивалентен:

while (true)

тело цикла;

Объявления переменных в цикле for

Хотя в циклах for обычно используется только один счетчик, иногда могут возникать ситуации, когда нужно работать сразу с несколькими переменными. Для этого используется оператор Запятая. Например:

#include <iostream>

int main()

{

int aaa, bbb;

for (aaa = 0, bbb = 9; aaa < 10; ++aaa, –bbb)

std::cout << aaa << ” ” << bbb << std::endl;

return 0;

}

Этот цикл присваивает значения двум ранее объявленным переменным: aaa = 0 и bbb = 9. Только с каждой итерацией переменная aaa увеличивается на единицу, а bbb – уменьшается на единицу.

Результат выполнения программы:

0 9

1 8

2 7

3 6

4 5

5 4

6 3

7 2

8 1

9 0

Примечание: Вышеприведенный цикл можно переписать следующим образом:

#include <iostream>

int main()

{

for (int aaa = 0, bbb = 9; aaa < 10; ++aaa, –bbb)

std::cout << aaa << ” ” << bbb << std::endl;

return 0;

}

В этом случае запятая в объявлении переменных является частью синтаксиса, а не использованием оператора Запятая. Но эффект идентичен.

Использование циклов for в старых версиях С++

В старых версиях C++ переменные, объявленные в цикле for, не уничтожались при завершении этого цикла. Т.е. у вас могло получиться что-то вроде следующего:

for (int count=0; count < 10; ++count)

std::cout << count << ” “;

// В старых версиях С++ переменная count здесь не уничтожается

std::cout << “n”;

std::cout << “I counted to: ” << count << “n”; // поэтому мы можем использовать count даже здесь

Читайте также:  Мировые циклы и кризисы

Позднее это было запрещено, но вы все еще можете увидеть подобное в старом коде.

Вложенные циклы for

Подобно другим типам циклов, одни циклы for могут быть вложены в другие циклы for. В следующем примере мы разместили один for внутри другого for:

#include <iostream>

int main()

{

for (char c = ‘a’; c <= ‘e’; ++c) // внешний цикл по буквам

{

std::cout << c; // сначала выводим букву

for (int i = 0; i < 3; ++i) // внутренний цикл по числам

std::cout << i;

std::cout << ‘n’;

}

return 0;

}

С одной итерацией внешнего цикла выполняется три итерации внутреннего цикла. Следовательно, результат выполнения программы:

a012

b012

c012

d012

e012

Заключение

Циклы for являются наиболее часто используемыми циклами в языке C++. Несмотря на то, что их синтаксис, как правило, немного запутывает начинающих программистов, вы очень скоро к нему привыкните и ощутите всю мощь и удобство этих циклов.

Тест

Задание №1

Напишите цикл for, который выводит каждое четное число в диапазоне от 0 до 20.

Ответ №1

#include <iostream>

int main()

{

for (int count = 0; count <= 20; count += 2)

std::cout << count << std::endl;

return 0;

}

Задание №2

Напишите функцию sumTo(), которая принимает целочисленный параметр с именем value и возвращает сумму всех чисел от 1 до значения value.

Например, если значением value является 5, то sumTo(5) должен возвратить 15, исходя из 1 + 2 + 3 + 4 + 5.

Подсказка: Используйте переменную вне тела цикла для хранения суммы чисел, как в примере с функцией pow() в подзаголовке «Еще примеры циклов for».

Ответ №2

int sumTo(int value)

{

int total(0);

for (int count=1; count <= value; ++count)

total += count;

return total;

}

Задание №3

Что не так со следующим циклом?

// Выводим все числа от 8 до 0

for (uned int count=8; count >= 0; –count)

cout << count << ” “;

Ответ №3

Этот цикл for выполняется до тех пор, пока count >= 0. Другими словами, он работает до тех пор, пока переменная count не станет отрицательным числом. Однако, поскольку count является типа uned, то эта переменная никогда не сможет быть отрицательной. Следовательно, этот цикл бесконечный! Как правило, рекомендуется избегать использования типов uned в цикле, если на это нет веских причин.

Оценить статью:

Загрузка…

Источник

  • #1

Циклическиe операции FOR

Командой FOR задаётся список команд, которые выполняются с КАЖДЫМ элементом набора.

Набор* пишется внутри IN (…)

Список команд пишется внутри DO (…)

Командная строка выполняет эти команды раз за разом, при этом текущий элемент набора находится в переменной, заданной после %% (назовём ее переменной цикла).

Например,

FOR %%a IN (C:Users*.txt) DO echo %%a

выведет имена и путь ко всем файлам с расширением .txt в папке C:Users.

* Примеры под спойлером

Для команды For без ключей набором может являться:

1) Маска файлов* (или путь + маска файлов)

– в двойных кавычках, или без них:

IN (*.txt)

Результат: список файлов с расширением .txt в текущем каталоге.

IN (*.txt *.bat)

Результат: список файлов с расширениеми .txt и .bat в текущем каталоге.

IN (“C:Folder 1Doc_31-12-*.txt”)

Результат: тот же. Но поиск ведется в каталоге C:Folder 1 (заметьте с пробелом в имени);

имя файла начинается на Doc_31-12-

Прим.: FOR без ключа не умеет выводить список каталогов.

* маска файлов – это набор файлов, заданный с помощью подстановочных знаков * и/или ?

где * – обозначает 0 или больше любых символов в имени файла.

а ? – означает 0 или 1 любой символ в имени файла.

2) Строка

– в двойных кавычках, или без них:

Строкой считается любая последовательность символов, если она не содержит знаков маски * или ?

Смысл цикла здесь в том, чтобы разбить такую строку по пробелам (или знакам табуляции)

и выполнить с каждой подстрокой список команд.

FOR %%a IN (гитара рыбка) do echo Моя %%a

Результат:

Если мы хотим, чтобы какая-то из строк не “билась” по пробелам, укажем ее в двойных кавычках:

FOR %%a IN (гитара “дорогая рыбка”) do echo Моя %%~a

Результат:

Моя гитара

Моя дорогая рыбка

При этом, чтобы не выводились сами кавычки “” мы используем модификатор* ~ (тильда) при раскрытии переменной цикла %%~a

*О других модификаторах переменной цикла можно почитать здесь и здесь.

3) еще есть смешанный тип. Это когда в наборе стоит маска (1-й описанный тип), а через пробел Строка (2 тип)… ведет себя вполне ожидаемо, но вряд ли найдет себе применение.

О наборах для FOR с ключем /F далее в нижнем спойлере.

Ключ /F часто используется для построчного разбора файла, т.е.

FOR /f “usebackq delims=” %%a IN (“C:1.txt”) DO echo %%a

выведет все строки файла 1.txt, который находится в корне диска C.

UseBackQ (Use back quotes) означает, что набор с двойными кавычками* подразумевает передачу в цикл имени файла.

delims= означает, что в переменную %%a будет записана вся строка (без разделения по пробелу или знаку табуляции, т.к. стандартный разделитель заменен на NULL (пустой символ).

В такой вариации:

tokens=* приводит к тому же результату, что и delims=. Означает прекратить разбивку по разделителю после “0-го” токена, т.е. сразу же.

* Этот вариант необходим для работы с файлом, путь или имя которого содержит пробелы.

Можно было не использовать UseBackQ, тогда команда приняла бы вид:

FOR /f “tokens=” %%a IN (C:1.txt) DO echo %%a

но такая конструкция восприняла бы пробел в имени как определение нового файла, поэтому UseBackQ более приемлем.

** Примеры под спойлером

В цикле FOR /F вид задаваемого набора зависит от формы кавычек в IN (…), а также наличия ключевого слова UseBackQ

Виды наборов для FOR /F:

1) Набор файлов (задание маски недопустимо!)

без UseBackQ – задается без кавычек IN (…)

__с UseBackQ – может задаваться как в кавычках так и без них. IN (…) IN (“…”)

Функционал:

чтение содержимого файла(ов) построчно в переменную цикла!

Принцип работы:

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

Исключение:

принятый по-умолчанию разделитель (пробел и знак табуляции) для этой конструкции цикла не применяется.

А что получится, если установить delims= (возле равно – знак пробела) ?

FOR /F “delims= ” %%a in (1.txt) do echo %%a

В выводе на экран командой Echo %%a мы получим содержимое файла, где каждая из строк будет напечатана до первого встретившегося пробела.

2) Строка (допускаются практически любые символы)

без UseBackQ – задается с двойными кавычками IN (“…”)

__с UseBackQ – задается с одиночными прямыми кавычками IN (‘…’)

3) Команда (сначала выполняется она, а уже ее результаты обрабатываются циклом как строка(-и))

без UseBackQ – задается с одиночными прямыми кавычками IN (‘…’)

__с UseBackQ – задается с одиночными обратными кавычками IN (`…`)

Читайте также:  Почему невозможен цикл карно

Примеры:

1.1. Чтение файла – Набор файлов

FOR /F %%a IN (c:users1.txt c:users2.txt) do echo.%%a

Результат: выведет подряд содержимое двух файлов – 1.txt и 2.txt из каталога c:users

Прим.: Echo. – с точкой – это обход ошибки, чтобы можно было напечатать пустую строку, точнее строку с пробелами.

1.2. Чтение файла – Набор файлов + UseBackQ

Получаем возможность использовать пробелы.

FOR /F “usebackq” %%a IN (“c:folder 11.txt”) do echo.%%a

Результат: выведет содержимое файла 1.txt из каталога c:folder 1

(заметьте, в имени папки есть пробел).

2.1. Строка

FOR /F %%a in (“Каждое слово в отдельную переменную”) echo a=%%a; b=%%b; c=%%c; d=%%d; e=%%e

Результат написал(а):

a=Каждое; b=слово; c=в; d=отдельную; e=переменную

2.2. Строка + UseBackQ

FOR /F “UseBackQ” %%a in (‘Каждое слово в отдельную переменную’) echo a=%%a; b=%%b; c=%%c; d=%%d; e=%%e

Результат такой же.

3.1. Команда

For /F “tokens=1-4” %%a IN (‘Dir /A:D-L’) Do Echo Папка %%d Дата модификации %%a. Время %%b

Сначала выполняется Dir /L, которая выводит информацию о папках в текущем каталоге.

Вот что попадает под разбор циклу:

Далее цикл разбирает каждую строку по пробелам и табуляции на подстроки (токены).

На примере 1-й строки:

1-й токен (%%a)=29.12.2012 …2-й токен (%%b)=15:16 …3-й токен (%%c)=<DIR> …4-й токен (%%d)=Favorites

Результат через Echo выводится на экран:

Папка Favorites Дата модификации 29.12.2012. Время 15:16

Папка s Дата модификации 14.01.2013. Время 01:51

…и т.д.

3.2. Команда + UseBackQ

For /F “Usebackq tokens=1-4” %%a IN (`Dir /A:D-L`) Do Echo Папка %%d Дата модификации %%a. Время %%b

Результат такой же.

Альтернативный вариант нужен с целью, если одна из выполняемых команд требует точно такие же кавычки как и ключевое слово IN (…).

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

Отличительной особенностью FOR /F является умение работать через токены*,

а также поддержка дополнительных ключевых слов:

1) eol – знак комментария в начале строки (1-й символ). Т.е. строки с таким символом не будут обрабатываться. (по умолчанию, знак точки с запятой ; )

2) skip – пропуск определенного кол-ва обрабатываемых строк от начала файла

3) delims – задать другой разделитель(-ли) (по умолчанию, пробел и знак табуляции)

4) tokens – количество получаемых токенов (подстрок) в теле цикла и пределы разбивки по разделителю.

Также можно задать конкретный № токена, который попадет в первую переменную цикла.

5) usebackq – изменение правил использования кавычек внутри IN (…)

Детальную справку можно получить, введя в консоль команду FOR /?

* Токены – это подстроки, которые попадают в переменные цикла %% в каждой из итераций.

Они получаются в результате разбивки строки, заданной в IN (…), по разделителю, заданному в Delims= (по умолчанию, пробел и знак табуляции).

В отличие, от FOR без ключа, в FOR /F все токены (все подстроки одной строки) попадают сразу В ПЕРВУЮ ИТЕРАЦИЮ цикла.

Они будут распределены по РАЗНЫМ переменным цикла, идущим в алфавитном порядке*, начиная с буквы, заданной после FOR /F %%

Т.е.

FOR /F %%a IN (“гитара рыбка”) do echo Моя %%a и моя %%b.

Результат:

*

Максимальное кол-во токенов составляет – 26,

если начальным указать %%a либо %%A (регистр имеет значение)

При этом переход с %%z в %%A не происходит. Остальная часть подстрок опускается.

Можно проверить:

For /F “tokens=1,2” %%z IN (“1 2”) do echo %%A

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

Метод показал Anonymоus в теме Символ переноса строки в переменной окружения

Алгоритм заключается в замене разделителя на пробел с одновременным заключением каждого токена в двойные кавычки. Далее строка разбирается обычным циклом FOR без ключа.

Более универсальные конструкции на основе FOR /F для работы с файлами/папками строятся путем помещения

в IN (‘…’) команды, результаты от выполнения которой уж затем обрабатываются циклом.

Чаще всего это команда Dir.

1.2. Чтение файла (сложный пример).

Давайте возьмем сложный пример, и раскусим “крепкий орешек”

FOR /F “UseBackQ skip=1 tokens=2 delims=/ eol=” %%X in (“%~dp01.txt”) do echo %%X

Имеем в распоряжении файл 1.txt, который находится рядом с батником.

Содержимое файла 1.txt написал(а):

первая строка

;комментарий/кода

наше любимоеблюдо

Порядок разбора (или “как прибл. будет думать ком. строка”):

1) %~dp0 – означает каталог, где находится батник, например c:temp

2) UseBackQ, ага – значит если в IN (…) ничего нет или двойные кавычки, то это файл и его нужно прочесть.

3) Читаем содержимое файла 1.txt в папке %~dp0, а затем каждую его строку проверяем по правилам… ключевых слов skip=1 tokens=2 delims=/ eol=

4) Итак, первая строка так и называется “первая строка”

skip=1 – означает пропустить от начала файла 1-у строку,

значит идем дальше:

5) Вторая строка: “;комментарий/кода”

Первый символ – это точка с запятой. А теперь смотрим сюда “eol=пустой символ”.

По умолчанию eol=; и если бы мы не указали пустой EOL, то цикл просто бы пропустил эту строку.

Итак, символ комментария не совпадает с заданным (т.е. он вообще пустой), а значит строчка нам подходит -> проверяем ее дальше:

6) Смотрим какие приняты разделители: delims=/ (знаки / и ), значит

из строки “;комментарий/кода”

мы получим 2 подстроки:

1-й токен – “;комментарий”

2-й токен – “кода”

7) Теперь смотрим сюда tokens=2 – значит, что первой букве цикла нужно присвоить значение 2-го токена.

Первая буква цикла у нас X. Переменная называется %%X

А второй токен – это подстрока “кода”

8) Только теперь мы попадаем в тело цикла: Echo %%X

что означает – вывести на экран текст “кода”

С 3-ей строкой потренируйтесь самостоятельно.

Ключ /L

FOR /L %%a IN (0,2,6) DO echo %%a

IN (первое, шаг, последнее)

означает математическое перечисление чисел от первого числа (0), до третьего (6), с шагом, указанным вторым числом (2) в наборе IN (…).

Указанная команда выведет:

Прим.: дробные числа командной строкой не поддерживаются.

  • #2

Продолжение…

Особенности, которые распространяются на циклы FOR

0) Если нужно записать в наборе несколько команд, то используем:

а) знаки амперсанда &, если мы хотим записать все в одну строку:

FOR /L %%a IN (1,1,10) DO echo Найден файл:& echo %%a

б) знаки скобок, если хотим разбить команды в несколько строк для наглядности и удобства:

FOR /L %%a IN (1,1,10) DO ( echo Найден файл: echo %%a )

1) Пустые строки в содержимом файлов и выводе команд игнорируются.

2) Если предполагается получение пустого токена, остальные токены смещаются.

К примеру,

имеем файл с содержимым:

file.txt написал(а):

Применим команду:

FOR /F “tokens=1,2,3 delims=/” %%a in (file.txt) do echo a=%%a; b=%%b; c=%%c

Результат будет:

cmd написал(а):

вместо ожидаемого

cmd написал(а):

3) Все специальные (служебные) символы необходимо экранировать (предварять птичкой ^).

Это такие символы, как | = ^ < > &. А также % ! – если они используются не для раскрытия переменной, кроме случая с !, когда не включено удаленное расширение переменных.

Читайте также:  Сколько ановуляторных цикла в год у женщины

Сюда же входит знак кавычки, которая соответствует форме кавычки, применяемой для определения вида набора.

4) Регистр переменной цикла имеет значение.

5) Изменить вручную значение переменной цикла нельзя. Например, set %%A=param не даст эффекта.

6) После выхода из цикла переменная цикла уничтожается.

7) Внутри цикла можно использовать не более 1-го комментария вида :: (иначе, будет критическая ошибка и “вылет” из пакетного файла)

Вместо этого используем Rem.

8) Внутри цикла можно использовать не более 1-й метки (иначе, будет такой же “вылет”).

Пример максимально допустимой конструкции:

@echo off for %%n in ( 0 1 2 3 4 5 6 7 8 9 ) do ( :label echo %%n :: echo %%n )

9) Тем не менее из цикла можно безвозвратно выйти на метку Goto metka

а также выйти в подпрограмму и вернутся снова в цикл точно в ту же позицию через команду Call :metka

В конце подпрограммы должна стоять команда Exit /B

10) Для получения значения обычной переменной внутри цикла в случае, если этой переменной было присвоено новое значение внутри тела этого же цикла, необходимо раскрывать переменную через знаки восклицания !variant! – это называется отложенное расширение переменных.

Перед использованием такого способа, его нужно включить, задав в начале пакетного файла команду:

SetLocal EnableDelayedExpansion

Иначе, если использовать обычный способ раскрытия %variant%, мы получим значение переменной, присвоенное ей еще до входа в цикл.

Точно таким же образом (через ! ) необходимо раскрывать переменную времени внутри цикла, т.к. иначе для цикла время “замерзает”.

Происходит это потому, что в цикл попадает т.н. “слепок” переменных среды. И работа с ними через % происходит уже как с копией данных, а не актуальными значениями.

11) Когда после IN указана команда, под разбор цикла попадают такие потоки:

1-й поток (StdOut)

с 3-го по 9-й поток (User Stream)

При этом 2-й поток (StdError) отображается на экране сразу после выполнения указанной в цикле команды в IN (…)

2-й поток можно занулить, обычным способом, не забыв экран:

FOR /F %%A IN (‘dir %someparam% 2^>nul’) do rem

Также можно перенаправить 2-й поток, чтобы он обрабатывался вместе с первым, вместо его вывода на экран:

FOR /F %%A IN (‘dir %someparam% 2^>^&1’) do rem

Собственно, чтобы наоборот, обрабатывать 2-й поток вместо первого, можно воспользоваться следующей конструкцией:

FOR /F %%A IN (‘dir %someparam% 1^>nul 2^>^&3’) do rem

12) При запуске цикла из консоли (cmd.exe) переменные цикла нужно указывать без удвоения знака процента %a.

Это же правило касается вызова цикла через Shell-подобные команды на других языках программирования.

13) Переменную цикла нельзя раскрыть внутри строки модификаторов другого цикла:

for /f %%q in (quote) do for /f “usebackq tokens=1* delims=%%q” %%a in (“%~dp01.txt”) do echo %%a%%b

но есть способ обхода от ComSpec:

Как известно, значение переменной цикла нельзя просто подставить в качестве модификатора в другой, вложенный, цикл:

for /f “tokens=2” %i in (“1 3 5”) do @for /f “tokens=%i” %j in (“1 3 5 7 9″) do @echo %j Результатом такой подстановки будет вывод ошибки: [quote] Непредвиденное появление: %i”. [/quote] Если же сделать так: [code] for /f “tokens=2” %i in (“1 3 5”) do @set x=%i for /f “tokens=%x%” %j in (“1 3 5 7 9”) do @echo %j

то ошибки не будет:

Но как всё же осуществить корректный вывод во вложенном цикле?

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

for /f “tokens=2” %i in (“1 3 5”) do @set x=%i& cmd/v/c for /f “tokens=!x!” %j in (“1 3 5 7 9”) do @echo %j

результат:

Непредвиденное появление: !x!”.

Оказалось, что это можно сделать проще, а именно просто запустить вложенный цикл в новом экземпляре интерпретатора:

for /f “tokens=2” %i in (“1 3 5”) do @cmd/c for /f “tokens=%i” %j in (“1 3 5 7 9”) do @echo %j

результат:

Последнее редактирование: 28 Июн 2016

  • #3

Продолжение…

Практические примеры:

1) Использование ключа /D

(спасибо sov44) Переименовать файл в имя папки

2) первый по алфавиту файл

for /F %%i in (“*.txt”) do set FILE_NAME=%%~nxi

Берет первый по алфавиту файл, заданный маской *.txt, и сразу выходит из цикла.

Можно также задавать конкретный путь перед маской.

(спасибо pistol за найденный пример.)

3) Использование модификатора %~$ПУТЬ:I для поиска файла в папках, заданных переменной среды Path:

for %%a in (“wmic.exe”) do echo %%~s$PATH:a

где:

wmic.exe – наш искомый файл

help написал(а):

Переменная среды ПУТЬ (в примере PATH), и переменная %a

заменяется на полное имя первого найденного файла.

Если переменная ПУТЬ не определена или в результате поиска

не найден ни один файл, то этот модификатор заменяется на пустую строку.

4) Разбивка текста по разделителям

for %%i in (text) do echo %%i

где text – текст, разбивка на итерации которого происходит по знакам:

  • пробел
  • парные кавычки *
  • табуляция
  • запятая
  • точка с запятой
  • знак равенства.

* Примечание от ComSpec:

Надо бы ещё исключить кавычки из перечня разделителей и написать, что парные двойные кавычки, наоборот, объединяют часть строки (или всю строку) вместе с перечисленными разделителями в одно “слово”, и при этом сами сохраняются, и если к ним справа или слева примыкает группа символов без разделителей, то она также входит в состав этого “слова”.

Исходя из сказанного, надо признать, что данный метод крайне ненадёжен для подсчёта слов (в обычном смысле понятия “слово”) в реальных текстах.

5) Удаление лидирующих нулей

:: математические операции со значениями 08 и 09 будут приводить к ошибкам set /a m=%:~3,2% :: поэтому для начала, удаляем лидирующие нули set m=%:~3,2% for /f “tokens=* delims=0” %%j in (“%m%”) do set m=%%j echo %m%

Дополнение от Smitis:

Если количество цифр в числе, в котором надо удалить лидирующие нули, известно заранее, то можно поступить так (для месяца из двух цифр)

:: В вычитаемом числе должно быть столько нулей, сколько цифр исходном числе. :: Исходное число должно быть не длинее 9-ти разрядов. set /a m=1%:~3,2%-100 echo %m%

Можно сразу подставлять такую конструкцию в нужное выражение.

Добавление лидирующих нулей: https://safezone.cc/threads/cmd-dobavit-lidirujuschie-nuli.32940/

6) Распределение итераций цикла for без ключей.

Дополнение: Получение пустых значений токенов в цикле с командой FOR

7) Использование кавычки в роле разделителя

Автор: amel27

for /f tokens^=1^,2^,3^ delims^=^” %%a in (“1″”2″”3”) do echo %%a–%%b–%%с

8) Циклическая конструкция с использованием сочетания модификаторов

(от ComSpec)

“tokens=* delims=<символы>”

является универсальным “триммером” для удаления любых заявленных символов из начала строки до первого незаявленного символа.

Пример:

for /f “tokens=* delims=0123456789” %i in (“972630014380333075vfh658weghui72qcfgb3658eyfgcb7652qweuy8”) do @echo %i

результат:

vfh658weghui72qcfgb3658eyfgcb7652qweuy8

9) получение результата выполнения программы в переменную

(если результатат – 1 строка)

for /f “delims= eol=” %%a in (‘file.exe’) do set “var=%%a”

Последнее редактирование: 18 Мар 2019

Источник