Давайте немного расскажу вам о функции 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:
Все на самом деле очень просто.
Спрашивайте свои ответы. Пишите пожелания, просьбы. Указывайте на мои ошибки.
Удачи!



Спасибо, статья помогла!
Я рад 🙂
Зацени мой новый блог на английском. Ссылка в шапке.