Аргументы функции main() и переменные окружения

Давайте немного расскажу вам о функции main и ее аргументах. А так же познакомимся с окружением пользователя в Linux. Как работать с переменными окружения, что они из себя представляют и так далее.

Прошу под кат.

Функция main — это основная точка входа в программу. Именно с нее начинается выполнение программы. Ей можно передавать аргументы. Если вы работали с консолью, не важно в windows или unix системах, то вы знаете, что программам можно передавать какие-то значения. Эти значения записываются в аргументы функции main, если они объявлены, иначе просто будут проигнорированы. Стандарт ANSI говорит нам объявлять функцию main следующим образом:

int main(int argc, char* argv[]);

Первый аргумент — это количество аргументов переданных в программу(arguments counter), причем имя программы тоже учитывается. Второй аргумент — это массив(из строк) значений аргументов(arguments values), последний элемент массива равен NULL.

Примечание: возвращаемое значение указывает на код ошибки, или равно нулю — если все прошло успешно. Но опять таки, все зависит от используемого стандарта, ОС и прочих факторов.

Теории хватит, потренеруемся. Напишем программу которая сообщит количество переданных параметров:

#include <stdio.h>

int main(int argc, char* argv)
{
	printf("%irn", argc - 1);
	return 0;
}

Результат:

Все просто. Теперь давайте сделаем программу которая будет складывать два числа переданных ей в качестве аргументов:

#include <stdio.h>

int main(int argc, char* argv[])
{
	if (argc == 3)
	{
		int a = atoi(argv[1]), b = atoi(argv[2]);
		printf("%irn", a + b);
		return 0;
	}
	else
		return -1;
}

Функция atoi преобразовывает строковое значение в int. А дальше все просто.

Теперь немного о среде окружения. Переменные окружения имеют следующий вид:

NAME = value

Где name — имя, а value — значение(странно, правда?). Хранятся они в массиве строк. Называется он environ. Его нужно объявить как внешнюю переменную типа char**.

Давайте выведем список всех переменных окружения на экран, что бы разобраться как он устроен:

#include <stdio.h>

extern char** environ;

int main(int argc, char* argv[])
{
	int i;
	for (i = 0; environ[i] != NULL; ++i)
		printf("[%i] %srn", i, environ[i]);
	return 0;
}

В результате у меня получилось 34 переменных, вот их часть на скриншоте:

Теперь ознакомимся с двумя функциями:

char * getenv (const char * name); //получает значение переменной name
int setenv (const char * name, const char * value, int overwrite); //создает новую переменную

Они нам понадобятся для более сложного задания. Перейдем сразу к нему. И так, нам необходимо создать переменную ENVVARS со значением всех имен переменных окружения и их значениями. Между именем и значением используется разделитель ‘-‘, а между парами «имя-значение» — ‘;’. Напишем сначала две функции, первая будет вытаскивать из строки переменной окружения ее имя:

char* GetName(const char* input)
{
	char* result = (char*) malloc(sizeof(input));
	int i;
	for (i = 0; input[i] != '='; ++i)
		result[i] = input[i];
	result[i] = '�';
	return result;
}

Принцип простой. Выделяем для нашей строки память размером с входящую строку, так точно хватит. После начинаем перебирать входящую строку, пока не встретим ‘=’, при этом копируем каждый символ в нашу результирующую строку. По достижении символа ‘=’ выходим из цикла, и присваиваем символу результирующей строки под номером i символ конца строки. Строка готова!

Теперь аналогичную, но только для значения:

char* GetValue(const char* input)
{
	char* result = (char*) malloc(sizeof(input));
	int i = 0;
	do
		++i;
	while (input[i] != '=');
	++i;
	int j;
	for (j = 0; input[i] != '�'; ++j, ++i)
		result[j] = input[i];
	result[j] = '�';
	return result;
}

Немного сложнее. Сначала ищем номер символа ‘=’. Нашли — увеличиваем переменную с номером(i) на единицу. Создаем новую переменную j. Начинаем цикл, в котором перебираем j, и увеличиваем переменную i. Каждому символу результирующей строки с номером j присваиваем символ входящей строки с номером i. И так пока не встретим символ конца строки в input. После присваиваем символу результирующей строки с номером j — ‘=’. Строка готова.

Примечание: функции можно было бы упростить, используя string.h. В нем объявлены функции для поиска номера символа в строке и т.д.. Так же можно было бы использовать getenv. Но для более глубокого понимания, следует уметь переписать всю стандартную библиотеку самостоятельно! Только работа с памятью, только хардкор!

Теперь можно приступить к написанию самой программы. Функция main будет выглядеть так:

int main(int argc, char* argv[])
{
	char* name = "ENVVARS"; //имя переменной окружения
	char* value = NULL; //значение переменной окружения
	int i;
	for (i = 0; environ[i] != NULL; ++i)
	{
		int size = 0;
		//если value еще не инициализирован
		if (value == NULL)
		{
			//размер равен размеру самой переменной окружения
			//кроме того 2 символа на '-' и ';' и 1 символ на '�'
			size = (strlen(environ[i]) + 3) * sizeof(char);
			value = (char*) malloc(size); //выделяем память
			value[0] = '�'; //делаем из value строку
		}
		//если value уже проинициализирован
		else
		{
			//новый размер равен сумме самого value + размер переменной окружения
			//аналогично инициализации еще 3 дополнительных символа
			size = strlen(value) + (strlen(environ[i]) + 3) * sizeof(char);
			value = (char*) realloc(value, size); //перераспределяем память
			value[strlen(value)] = '�'; //делаем строку
		}
		strcat(value, GetName(environ[i])); //добавляем имя
		AppendChar(value, '-'); //добавляем символ
		strcat(value, GetValue(environ[i])); //добавляем значение
		AppendChar(value, ';'); //добавляем символ

	}
	//добавим нашу переменную в окружение
	setenv(name, value, 0);
	for (i = 0; environ[i] != NULL; ++i)
		printf("%srn", environ[i]);
    free(name); //освобождаем память
    free(value); //еще разок, но уже для value
}

Функция AppendChar добавляет символ в конец строки. В стандартной библиотеки такой функции не было, поэтому я написал свою:

void AppendChar(char* input, char character)
{
	char* c = (char*) malloc(sizeof(char) * 2);
	c[0] = character;
	c[1] = '�';
	strcat(input, c);
}

В консоль будет выведен список всех переменных окружения, в конце которого будет можно найти переменную с именем ENVVARS:

Все на самом деле очень просто.

Спрашивайте свои ответы. Пишите пожелания, просьбы. Указывайте на мои ошибки.

Удачи!

Комментарии 1

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *