Параметры функции main (argc, argv)
При создании консольного приложения в языке программирования С++, автоматически создается строка очень похожая на эту:
int main(int argc, char* argv[]) // параметры функции main()
Эта строка — заголовок главной функции main() , в скобочках объявлены параметры argс и argv. Так вот, если программу запускать через командную строку, то существует возможность передать какую-либо информацию этой программе, для этого и существуют параметры argc и argv[] . Параметр argc имеет тип данных int , и содержит количество параметров, передаваемых в функцию main . Причем argc всегда не меньше 1, даже когда мы не передаем никакой информации, так как первым параметром считается имя функции. Параметр argv[] это массив указателей на строки. Через командную строку можно передать только данные строкового типа. Указатели и строки — это две большие темы, под которые созданы отдельные разделы. Так вот именно через параметр argv[] и передается какая-либо информация. Разработаем программу, которую будем запускать через командную строку Windows, и передавать ей некоторую информацию.
// argc_argv.cpp: определяет точку входа для консольного приложения. #include "stdafx.h" #include using namespace std; int main(int argc, char* argv[]) < if (argc >1)// если передаем аргументы, то argc будет больше 1(в зависимости от кол-ва аргументов) < cout else < cout system("pause"); return 0; >
// argc_argv.cpp: определяет точку входа для консольного приложения. #include using namespace std; int main(int argc, char* argv[]) < if (argc >1)// если передаем аргументы, то argc будет больше 1(в зависимости от кол-ва аргументов) < cout else < cout return 0; >
После того как отладили программу, открываем командную строку Windows и перетаскиваем в окно командной строки экзэшник нашей программы, в командной строке отобразится полный путь к программе(но можно прописать путь к программе в ручную), после этого можно нажимать ENTER и программа запустится (см. Рисунок 1).
Рисунок 1 — Параметры функции main
Так как мы просто запустили программу и не передавали ей никаких аргументов, появилось сообщение Not arguments . На рисунке 2 изображён запуск этой же программы через командную строку, но уже с передачей ей аргумента Open .

Рисунок 2 — Параметры функции main
Аргументом является слово Open , как видно из рисунка, это слово появилось на экране. Передавать можно несколько параметров сразу, отделяя их между собой запятой. Если необходимо передать параметр состоящий из нескольких слов, то их необходимо взять в двойные кавычки, и тогда эти слова будут считаться как один параметр. Например, на рисунке изображен запуск программы, с передачей ей аргумента, состоящего из двух слов — It work .

Рисунок 3 — Параметры функции main
А если убрать кавычки. То увидим только слово It . Если не планируется передавать какую-либо информацию при запуске программы, то можно удалить аргументы в функции main() , также можно менять имена данных аргументов. Иногда встречается модификации параметров argc и argv[] , но это все зависит от типа создаваемого приложения или от среды разработки.
К сожалению, для данной темы пока нет подходящих задач. Если у вас есть таковые на примете, отправте их по адресу: admin@cppstudio.com. Мы их опубликуем!
Main() и аргументы командной строки
Метод Main — это точка входа приложения C#. (Библиотекам и службам не требуется Main метод в качестве точки входа.) При запуске Main приложения метод является первым вызываемого метода.
В программе на C# может существовать только одна точка входа. Если у вас есть несколько классов с методом Main , программу нужно компилировать с параметром компилятора StartupObject, чтобы указать, какой из методов Main будет использоваться в качестве точки входа. Дополнительные сведения см. в разделе StartupObject (параметры компилятора C#).
class TestClass < static void Main(string[] args) < // Display the number of command line arguments. Console.WriteLine(args.Length); >>
Инструкции верхнего уровня можно также использовать в одном файле в качестве точки входа для приложения:
using System.Text; StringBuilder builder = new(); builder.AppendLine("Hello"); builder.AppendLine("World!"); Console.WriteLine(builder.ToString());
Обзор
- Метод Main — это точка входа для выполняемой программы. Это начальный и завершающий этапы управления программой.
- Main объявляется внутри класса или структуры. Main должно быть static , и это не должно быть public . (В предыдущем примере он получает доступ private по умолчанию .) Вложенный класс или структуру не требуется быть статическим.
- Main может иметь void тип , int Task или Task возвращаемый тип.
- Если только Main возвращает Task или Task , объявление Main может включать модификатор async . Это, в частности, исключает async void Main метод.
- Метод Main может быть объявлен с параметром string[] , который содержит аргументы командной строки, или без него. При использовании Visual Studio для создания приложений Windows можно добавить параметр вручную или использовать GetCommandLineArgs() метод для получения аргументов командной строки. Параметры считываются как аргументы командной строки, индексы которых начинаются с нуля. В отличие от C и C++, имя программы не рассматривается как первый аргумент командной строки в массиве args , но является первым элементом метода GetCommandLineArgs().
В следующем списке показаны допустимые Main подписи:
public static void Main() < >public static int Main() < >public static void Main(string[] args) < >public static int Main(string[] args) < >public static async Task Main() < >public static async Task Main() < >public static async Task Main(string[] args) < >public static async Task Main(string[] args)
В предыдущих примерах все используют public модификатор доступа. Это типично, но не обязательно.
Добавление значений async и Task , а также типов возвращаемого значения Task упрощает код программы, когда консольным приложениям требуется запустить и ожидать ( await ) асинхронные операции в Main .
Возвращаемые значения Main()
Вы можете возвратить int из метода Main , определив метод одним из следующих способов:
| Код метода Main | Сигнатура Main |
|---|---|
| Без использования args или await | static int Main() |
| С использованием args , без использования await | static int Main(string[] args) |
| Без использования args , с использованием await | static async Task Main() |
| С использованием args и await | static async Task Main(string[] args) |
Если значение, возвращаемое методом Main , не используется, возврат void или Task несколько упрощает код.
| Код метода Main | Сигнатура Main |
|---|---|
| Без использования args или await | static void Main() |
| С использованием args , без использования await | static void Main(string[] args) |
| Без использования args , с использованием await | static async Task Main() |
| С использованием args и await | static async Task Main(string[] args) |
Однако возврат int или Task позволяет программе передавать информацию о своем состоянии другим программам и скриптам, которые вызывают исполняемый файл.
В следующем примере показано, как можно получить доступ к коду завершения для процесса.
В этом примере используются программы командной строки .NET Core. Если вы не знакомы с программами командной строки .NET Core, можете обратиться к этой статье по началу работы.
Создайте приложение, выполнив команду dotnet new console . Измените Main метод в Program.cs следующим образом:
// Save this program as MainReturnValTest.cs. class MainReturnValTest < static int Main() < //. return 0; >>
При запуске программы в Windows значение, возвращаемое функцией Main , сохраняется в переменной среды. Эту переменную среды можно получить из пакетного файла с помощью ERRORLEVEL или в PowerShell с помощью $LastExitCode .
Для сборки приложения можно выполнить команду dotnet build интерфейса командной строки .NET.
Затем создайте скрипт PowerShell для запуска приложения и отображения результата. Вставьте следующий код в текстовый файл и сохраните его под именем test.ps1 в папке проекта. Запустите скрипт PowerShell, введя команду test.ps1 в командной строке PowerShell.
Так как код возвращает нулевое значение, пакетный файл сообщает об успехе. Но если изменить файл MainReturnValTest.cs, чтобы он возвращал ненулевое значение, и затем повторно скомпилировать программу, то при последующем выполнении скрипта PowerShell будет выдано сообщение об ошибке.
dotnet run if ($LastExitCode -eq 0) < Write-Host "Execution succeeded" >else < Write-Host "Execution Failed" >Write-Host "Return value = " $LastExitCode
Execution succeeded Return value = 0
Значения, возвращаемые асинхронным методом main
При объявлении возвращаемого значения Main компилятор создает стандартный async код для вызова асинхронных методов в Main . Если вы не указываете async ключевое слово, необходимо самостоятельно написать этот код, как показано в следующем примере. Код в примере гарантирует, что программа выполняется до завершения асинхронной операции:
class AsyncMainReturnValTest < public static void Main() < AsyncConsoleWork().GetAwaiter().GetResult(); >private static async Task AsyncConsoleWork() < // Main body here return 0; >>
Этот стандартный код можно заменить следующими способами:
class Program < static async TaskMain(string[] args) < return await AsyncConsoleWork(); >private static async Task AsyncConsoleWork() < // main body here return 0; >>
Преимущество объявления Main как async того, что компилятор всегда создает правильный код.
Если точка входа приложения возвращает Task или Task , то компилятор создает новую точку входа, которая вызывает метод точки входа, объявленный в коде приложения. Предположим, что эта точка входа называется $GeneratedMain . В этом случае компилятор создает следующий код для этих точек входа:
- static Task Main() приводит к тому, что компилятор формирует эквивалент private static void $GeneratedMain() => Main().GetAwaiter().GetResult();
- static Task Main(string[]) приводит к тому, что компилятор формирует эквивалент private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
- static Task Main() приводит к тому, что компилятор формирует эквивалент private static int $GeneratedMain() => Main().GetAwaiter().GetResult();
- static Task Main(string[]) приводит к тому, что компилятор формирует эквивалент private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
Если бы в примерах использовался модификатор async метода Main , компилятор сформировал бы точно такой же код.
Аргументы командной строки
Вы можете передавать аргументы в метод Main , определив метод одним из следующих способов:
| Код метода Main | Сигнатура Main |
|---|---|
| Без возвращаемого значения, без использования await | static void Main(string[] args) |
| С возвращаемым значением, без использования await | static int Main(string[] args) |
| Без возвращаемого значения, с использованием await | static async Task Main(string[] args) |
| С возвращаемым значением, с использованием await | static async Task Main(string[] args) |
Если аргументы не используются, можно опустить args в сигнатуре метода, чтобы немного упростить код:
| Код метода Main | Сигнатура Main |
|---|---|
| Без возвращаемого значения, без использования await | static void Main() |
| С возвращаемым значением, без использования await | static int Main() |
| Без возвращаемого значения, с использованием await | static async Task Main() |
| С возвращаемым значением, с использованием await | static async Task Main() |
Вы также можете использовать Environment.CommandLine или Environment.GetCommandLineArgs получать доступ к аргументам командной строки из любой точки в консоли или приложении Windows Forms. Чтобы включить аргументы командной строки в Main сигнатуре метода в приложении Windows Forms, необходимо вручную изменить подпись Main . Код, созданный конструктором Windows Forms, создает Main без входного параметра.
Параметр метода Main — это массив String, представляющий аргументы командной строки. Как правило, определить, существуют ли аргументы, можно, проверив свойство Length , например:
if (args.Length == 0)
Массив args не может иметь значение NULL. Поэтому доступ к свойству Length можно получить без проверки значения NULL.
Строковые аргументы также можно преобразовать в числовые типы с помощью класса Convert или метода Parse . Например, следующая инструкция преобразует string в число long с помощью метода Parse:
long num = Int64.Parse(args[0]);
Можно также использовать тип C# long , который является псевдонимом Int64 :
long num = long.Parse(args[0]);
Кроме того, можно использовать метод класса Convert , ToInt64 :
long num = Convert.ToInt64(s);
Дополнительные сведения см. в разделах Parse и Convert.
В следующем примере показано использование аргументов командной строки в консольном приложении. Приложение принимает один аргумент времени выполнения, преобразует аргумент в целое число и вычисляет факториал числа. Если не указано никаких аргументов, приложение выдает сообщение, поясняющее правильное использование программы.
Чтобы скомпилировать и запустить приложение из командной строки, выполните следующие действия.
-
Вставьте следующий код в любой текстовый редактор и сохраните файл как текстовый файл с именем Factorial.cs.
public class Functions < public static long Factorial(int n) < // Test for invalid input. if ((n < 0) || (n >20)) < return -1; >// Calculate the factorial iteratively rather than recursively. long tempResult = 1; for (int i = 1; i return tempResult; > > class MainClass < static int Main(string[] args) < // Test if input arguments were supplied. if (args.Length == 0) < Console.WriteLine("Please enter a numeric argument."); Console.WriteLine("Usage: Factorial "); return 1; > // Try to convert the input arguments to numbers. This will throw // an exception if the argument is not a number. // num = int.Parse(args[0]); int num; bool test = int.TryParse(args[0], out num); if (!test) < Console.WriteLine("Please enter a numeric argument."); Console.WriteLine("Usage: Factorial "); return 1; > // Calculate factorial. long result = Functions.Factorial(num); // Print result. if (result == -1) Console.WriteLine("Input must be >= 0 and <= 20."); else Console.WriteLine($"The Factorial of is ."); return 0; > > // If 3 is entered on command line, the // output reads: The factorial of 3 is 6.
При выполнении приложения в Visual Studio аргументы командной строки можно указать на странице «Отладка» в конструкторе проектов.
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
См. также
- System.Environment
- Отображение аргументов командной строки
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
The .NET documentation is open source. Provide feedback here.
Обратная связь
Отправить и просмотреть отзыв по
C#. Метод main(). Способы объявления
Метод Main() . Способы объявления. Передача аргументов в функцию Main() . Метод GetCommandLineArgs() класса Environment
Поиск на других ресурсах:
1. Назначение метода Main() . Особенности применения
Функция Main() – это специальная функция, которая предназначена для начала выполнения любой программы и имеет следующие особенности применения:
- функция Main() есть точкой входа в любую программу на языке C#. Термин «точка входа» означает, что выполнение программы начинается из функции Main() ;
- функция Main() считается главной функцией в программе, которая может вызывать другие функции, реализованные в программе;
- функция Main() может получать параметры. С помощью этих параметров другая программа может передавать некоторую информацию (данные) в текущую программу;
- функция Main() может возвращать целочисленное значение, которое будет сигнализировать о результате выполнения программы. Это необходимо в случаях, если программа вызывается из другой программы (процесса). Чаще всего процессом, который вызывает функцию Main() есть операционная система;
- в программе функция с именем Main() может быть только одна. Иными словами, функция Main() не может быть перегружена;
- функция Main() есть статической, то есть в начале объявления содержит модификатор static . Это означает, что функция вызывается без создания экземпляра класса. Статичность функции необходима, так как при первом запуске еще не создано никаких экземпляров классов. Существуют только статические методы и переменные. Эти методы и переменные инициализируются автоматически при первом обращении к ним.
2. Способы объявления функции Main()
Функция Main() может быть объявлена одним из четырех возможных способов, перечисленных ниже.
Способ 1. Функция не возвращает значения и не получает параметров. Общая форма функции Main() в этом случае следующая:
static void Main() < // действия, операторы // . >
Способ 2. Функция возвращает целочисленное значение и не получает параметров. В этом случае общая форма функции следующая
static int Main() < // действия, операторы // . return value; >
Здесь value – некоторое целочисленное значение, которое есть результатом возврата из программы. Другие процессы, запускающие текущую программу, могут использовать этот результат. Например, если функция Main() возвращает -1, то это может означать внутреннюю ошибку. И, наоборот, если функция возвращает 0, то это может означать корректное выполнение программы.
Способ 3. Функция не возвращает значения, но получает параметры. Параметрами функции Main() может быть массив строк. В этом случае общая форма функции следующая:
static void Main(string[] args) < // действия, операторы // . >
- args – массив строк, который передается в функцию Main() из других процессов.
Способ 4. Функция возвращает целочисленное значение и получает параметры. Общая форма объявления функции следующая
static void Main(string[] args) < // действия, операторы // . return value; >
- args – массив строк, который передается в функцию Main() из других процессов;
- value – значение типа int , которое передается в процесс, который вызвал текущую программу.
3. Модификаторы доступа, которые могут применяться с функцией Main()
Функция Main() может быть объявлена с двумя модификаторами доступа:
- private – в этом случае функция Main() не может вызываться из других сборок непосредственно;
- public – функция Main() есть общедоступной из других сборок.
4. Зачем в качестве параметров в функцию Main() передается массив строк?
В качестве параметров в любую программу (функцию Main() ) вызывающий процесс (операционная система) может передать только строку символов. Если эта строка содержит слова, которые разделены символом пробел, то эта строка разбивается на массив строк.
Например. Пусть сделан вызов программы с именем Project1.exe следующим образом:
Project1.exe param1 param2 file1.txt
то функция Main() программы Project1.exe получит следующий массив входных параметров
param1 param2 file1.txt
то есть, для следующего объявления функции
void Main(string[] args) < // . >
значения переменной args будут следующими:
args.Length = 3 args[0] = "param1" args[1] = "param2" args[2] = "file1.txt"
5. Пример, который демонстрирует применение параметров в функции Main()
В примере продемонстрирован вывод массива параметров на экран. Программа создана по шаблону Console Application.
using System; namespace ConsoleApp1 < class Program < static void Main(string[] args) < // Пример вывода массива параметров args на экран Console.WriteLine("args.Length = ", args.Length); for (int i = 0; i < args.Length; i++) < Console.WriteLine("args[] = ", i, args[i]); > > > >
Результат выполнения программы ConsoleApp1.exe для строки
ConsoleApp1 param1 param2 file1.txt
имеет следующий вид
args.Length = 3 args[0] = param1 args[1] = param2 args[2] = file1.txt
6. Установка параметров, которые передаются в функцию Main() , средствами Microsoft Visual Studio 2019
В системе Microsoft Visual Studio любой версии можно задавать параметры, которые передаются в функцию Main() . Эти параметры еще называются аргументы командной строки.
Чтобы задать аргументы командной строки используется команда Properties… из меню Project .
Например, если создано консольное приложение с именем решения ConsoleApp1 , то вызвать окно настройки параметров можно с помощью команды
Project -> ConsoleApp1 Properties.
как показано на рисунке 1.

Рисунок 1. Команда вызова свойств проекта
В результате откроется окно «ConsoleApp1» , в котором нужно активировать элемент Debug (рисунок 2). В левой части окна в поле «Application arguments» нужно ввести аргументы командной строки. Эти аргументы будут передаваться в функцию Main() . Таким образом, можно протестировать вызов текущей программы из других процессов передавая программе различные варианты аргументов.

Рисунок 2. Установка аргументов командной строки
7. Каким образом в функцию Main() передать строку, которая содержит пробелы?
Бывают случаи, когда в функцию Main() нужно передать строку как один параметр. Но эта строка может содержать пробелы. В этом случае строку нужно заключить в двойные кавычки. Все что размещается между двойными кавычками не разбивается по параметрам.
Например. Пусть в функцию Main() для приложения с именем ConsoleApp1.exe нужно передать два параметра-строки:
- «This is a parameter»;
- «Second parameter».
В этом случае, вызов ConsoleApp1.exe из другого процесса (например, из командной строки) будет следующим:
ConsoleApp1.exe "This is a parameter" "Second parameter"
В этом случае в функцию Main() будут переданы следующие значения массива args :
args.Length = 2 args[0] = "This is a parameter" args[1] = "Second parameter"
8. Получение параметров с помощью метода GetCommandLineArgs() класса Environment . Пример
Получить параметры командной строки можно с помощью метода GetCommandLineArgs() класса Environment . Этот метод есть статическим, а потому не нужно создавать экземпляр класса Environment . Метод возвращает массив аргументов типа string[] .
Важно помнить, что метод GetCommandLineArgs() возвращает массив параметров на один больше. Первым параметром, который возвращает метод (под индексом 0) идет полное имя к текущему выполняемому файлу.
Пример. Вывод на экран списка параметров, передаваемых в функцию Main() .
using System; namespace ConsoleApp1 < class Program < static void Main(string[] args) < // Вывести список параметров с помощью метода GetCommandLineArgs() // класса Environment string[] parameters = Environment.GetCommandLineArgs(); Console.WriteLine("Parameters:"); foreach (string s in parameters) < Console.WriteLine(s); > Console.ReadKey(); > > >
9. Определение полного имени файла выполняемой программы
Полное имя файла выполняемой программы можно определить с помощью статического метода GetCommandLineArgs() класса Environment. Как известно, метод используется для определения параметров текущей программы в виде массива строк типа string[] . При вызове метода, параметр, который возвращается, с индексом 0 содержит полное имя файла текущей программы.
Нижеследующий фрагмент кода демонстрирует вывод полного имени файла текущей программы
// Вывести полный путь к файлу текущей программы string path = Environment.GetCommandLineArgs()[0]; Console.WriteLine("Full path = ", path);
Связанные темы
- Понятие метода. Примеры методов в классах. Возврат из метода. Оператор return . Методы без параметров. Ключевое слово void
- Передача параметров в метод. Аргументы и формальные параметры. Примеры. Передача ссылки на объект класса в метод
Передача аргументов в программу
Бывает, что данные в программу передаются из командной строки при ее вызове. Такие данные называются аргументами командной строки. Выглядит это так, например:
./a.out test.txt ls -lt /home/peter/
Здесь вызываются программы a.out (из текущего каталога) и ls (из одного каталога, указанного в переменной окружения PATH). Первая программа из командной строки получает одно слово — test.txt, вторая — два: -lt и /home/peter/.
Если программа написана на языке C, то при ее запуске управление сразу передается в функцию main() , следовательно, именно она получает аргументы командной строки, которые присваиваются ее переменным-параметрам.
До этого мы определяли функцию main() так, как-будто она не принимает никакие параметры и ничего не возвращает. На самом деле в языке C любая функция по-умолчанию (если не определено ничего иного) возвращает целое число. В этом можно убедиться. Если записать код таким образом:
main() { printf("Hi\n"); return 0; }
, то ошибки при компиляции не возникнет (но будет предупреждение). То же самое будет, если записать int main() . Это доказывает, что функция по-умолчанию возвращает целое число, а не ничто ( void ). Хотя то, что возвращает функция всегда можно «переопределить», например, voidmain() или float main() .
При вызове программы из командной строки в нее всегда передается пара данных:
- целое число, обозначающее количество слов (элементов, разделенных пробелами) в командной строке при вызове,
- указатель на массив строк, где каждая строка — это отдельное слово из командной строки.
Само имя программы также считается. Например, если вызов выглядит так:
./a.out 12 theme 2
, то первый аргумент программы имеет значение 4, а массив строк определяется как .
Обратите внимание на терминологию, есть всего два аргумента программы (число и массив), но сколько угодно аргументов командной строки. Аргументы командной строки «преобразуются» в аргументы программы (в аргументы функции main() ).
Эти данные (число и указатель) передаются в программу даже тогда, когда она просто вызывается по имени без передачи в нее чего-либо: ./a.out. В таком случае первый аргумент имеет значение 1, а второй указывает на массив, состоящий всего из одной строки .
То, что в программу передаются данные, вовсе не означает, что функция main() должна их принимать. Если функция main() определена без параметров, то получить доступ к аргументам командной строки невозможно. Хотя ничего вам не мешает их передавать. Ошибки не возникнет.
Чтобы получить доступ к переданным в программу данным, их необходимо присвоить переменным. Поскольку аргументы сразу передаются в main() , то ее заголовок должен выглядеть таким образом:
int main(int n, char *arr[])
В первой переменной (n) содержится количество слов, а во второй — указатель на массив строк. Часто второй параметр записывают в виде **arr . Однако это то же самое. Вспомним, что сам массив строк, содержит в качестве своих элементов указатели на строки. А в функцию мы передаем указатель на первый элемент массива. Получается, что передаем указатель на указатель, т.е. **arr .
Напишите такую программу:
#include int main(int argc, char **argv) { int i; printf("%d\n", argc); for (i=0; i argc; i++) puts(argv[i]); }
Она выводит количество слов в командной строке при ее вызове и каждое слово с новой строки. Вызовите ее без аргументов командной строки и с аргументами.
В программе мы использовали переменные-параметры argc и argv. Принято использовать именно такие имена, но на самом деле они могут быть любыми. Лучше придерживаться этого стандарта, чтобы ваши программы были более понятны не только вам, но и другим программистам.
Практическое значение передачи данных в программу
Если у вас есть опыт работы в командной строке GNU/Linux, вы знаете, что у большинства команд есть ключи и аргументы. Например, при просмотре содержимого каталогов, копировании, перемещении в качестве аргументов указываются объекты файловой системы, над которыми выполняется команда. Особенности ее выполнения определяются с помощью ключей. Например, в команде
cp -r ../les_1 ../les_101
cp — это имя команды, -r — ключ, а ../les_1 и ../les_101 — аргументы команды.
Нередко в программы при их запуске передаются адреса файлов и «модификаторы» (это ключи) процесса выполнения программы.
Напишем программу, которая открывает указанные пользователем в командной строке файлы на запись или добавление и записывает (добавляет) туда одну и туже информацию, которую пользователь вводит с клавиатуры в процессе выполнения программы:
#include #include int main (int argc, char **argv) int i, ch; FILE *f[5]; if (argc 3 if (strcmp(argv[1], "-w") != 0 && strcmp(argv[1], "-a") != 0) { puts("Первый параметр -w или -a"); return 2; } for (i=0; i argc-2; i++){ f[i] = fopen(argv[i+2], argv[1]+1); if (f[i] == NULL) { printf("Файл %s нельзя открыть\n", argv[i+2]); return 3; } } while ((ch = getchar()) != EOF) for (i=0; i argc-2; i++) putc(ch,f[i]); for (i=0; i argc-2; i++) fclose(f[i]); return 0; }
Пояснения к коду:
- Создается массив из пяти файловых указателей. Следовательно можно одновременно открыть не более пяти файлов. Файловый указатель первого файла будет хранится в элементе массива f[0], второго — в f[1] и т.д.
- Проверяется количество аргументов командной строки. Их должно быть не меньше трех, т.к. первый — это имя программы, второй — режим открытия файла, третий — первый или единственный файл, в который будет производится запись. Поскольку программа позволяет открыть только пять файлов, то общее число аргументов командной строки не может быть больше семи. Поэтому если количество аргументов меньше 3 или больше 7, то программа завершается, т.к. оператор return приводит к выходу из функции, даже если после него есть еще код. Возвращаемое из функции значение неравное 0, может быть интерпретировано родительским процессом, как сообщение о том, что программа завершилась с ошибкой.
- Проверяется корректность второго аргумента командной строки. Если он не равен ни «-w», ни «-a», то условное выражение во втором if возвращает 1 (true). Функция strcmp() позволяет сравнивать строки и возвращает 0 в случае их равенства.
- В цикле for открываются файлы по указанным адресам, которые начинаются с третьего элемента массива argv. Именно поэтому к i прибавляется 2, чтобы получать элементы массива argv, начиная с третьего. Выражение argc-2 указывает на количество переданных имен файлов; т.к. в argc хранится общее число аргументов командной строки, первые два из которых не являются именами файлов.
- Выражение argv[1]+1 позволяет «вырезать» из строки «-w» (или «-a») подстроку «w» (или «a»), т.к. argv[1] по сути указатель на первый элемент строки. Прибавляя к указателю единицу, мы смещаем его к следующему элементу массива.
- Если файл отрыть не удается, то функция fopen() возвращает NULL. В таком случае программа завершается.
- Каждый символ, введенный пользователем с клавиатуры, записывается во все открытые файлы.
- В конце файлы закрываются.
Курс с решением части задач:
pdf-версия
