
Прошу под кат.
Функция main — это основная точка входа в программу. Именно с нее начинается выполнение программы. Ей можно передавать аргументы. Если вы работали с консолью, не важно в windows или unix системах, то вы знаете, что программам можно передавать какие-то значения. Эти значения записываются в аргументы функции main, если они объявлены, иначе просто будут проигнорированы. Стандарт ANSI говорит нам объявлять функцию main следующим образом:
1 |
int main(int argc, char* argv[]); |
Первый аргумент — это количество аргументов переданных в программу(arguments counter), причем имя программы тоже учитывается. Второй аргумент — это массив(из строк) значений аргументов(arguments values), последний элемент массива равен NULL.
Примечание: возвращаемое значение указывает на код ошибки, или равно нулю — если все прошло успешно. Но опять таки, все зависит от используемого стандарта, ОС и прочих факторов.
Теории хватит, потренеруемся. Напишем программу которая сообщит количество переданных параметров:
1 2 3 4 5 6 7 |
#include <stdio.h> int main(int argc, char* argv) { printf("%irn", argc - 1); return 0; } |
Результат:
Все просто. Теперь давайте сделаем программу которая будет складывать два числа переданных ей в качестве аргументов:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#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**.
Давайте выведем список всех переменных окружения на экран, что бы разобраться как он устроен:
1 2 3 4 5 6 7 8 9 10 11 |
#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 переменных, вот их часть на скриншоте:
Теперь ознакомимся с двумя функциями:
1 2 |
char * getenv (const char * name); //получает значение переменной name int setenv (const char * name, const char * value, int overwrite); //создает новую переменную |
Они нам понадобятся для более сложного задания. Перейдем сразу к нему. И так, нам необходимо создать переменную ENVVARS со значением всех имен переменных окружения и их значениями. Между именем и значением используется разделитель ‘-‘, а между парами «имя-значение» — ‘;’. Напишем сначала две функции, первая будет вытаскивать из строки переменной окружения ее имя:
1 2 3 4 5 6 7 8 9 |
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 символ конца строки. Строка готова!
Теперь аналогичную, но только для значения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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 будет выглядеть так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
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 добавляет символ в конец строки. В стандартной библиотеки такой функции не было, поэтому я написал свою:
1 2 3 4 5 6 7 |
void AppendChar(char* input, char character) { char* c = (char*) malloc(sizeof(char) * 2); c[0] = character; c[1] = '�'; strcat(input, c); } |
В консоль будет выведен список всех переменных окружения, в конце которого будет можно найти переменную с именем ENVVARS:
Все на самом деле очень просто.
Спрашивайте свои ответы. Пишите пожелания, просьбы. Указывайте на мои ошибки.
Удачи!
Спасибо, статья помогла!