TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.36K subscribers
Post #804 4.76K
​​std::getenv
#новичкам

Переменные окружения - это пары "ключ-значение", которые хранятся в операционной системе и доступны всем процессам. Они часто используются для:

- Конфигурации приложений
- Хранения чувствительных данных (паролей, ключей API)
- Управления поведением программ

Самый банальный пример - PATH. В этой переменной окружения находится список путей для поиска исполняемых файлов системой. Добавив путь к своей утилите в эту переменную, вы сможете ее запускать без указания полного пути.

Или например, более приближеный к плюсам пример, LD_LIBRARY_PATH. Это список путей, в котором линкер ищет указанные при линковке библиотеки.

И мы можем прочитать из плюсового кода переменные окружения с помощью С++11 функции std::getenv:

#include <cstdlib>

char* std::getenv(const char* name);


Это скоммунизженная из Сей функция, которая принимает имя переменной окружения и возвращает ее содержимое. Если искомой переменной не существует, возвращается nullptr.

Почему-то они решили возвращать неконстантный указатель, поэтому если уже в вашу голову пришла мысль как-то поменять данные по этому указателю, то не стоит этого делать. Получите UB.

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

Допустим, пишите вы какой-нибудь свой клиент-сервер на Boost.Asio. Хочется конфигурировать клиента адресом и портом сервера извне, чтобы иметь возможность по-разному запускать клиента локально и, допустим, через docker-compose. Конфиг и его парсилку писать довольно муторно, а адекватную парсилку аргументов командной строки - еще сложнее. Даже если использовать готовые решения в виде json парсера и boost.program_options.

Вместо этих решений можно передавать креды подключения к серверу через переменную окружения:

#include <boost/asio.hpp>
#include <iostream>
#include <cstdlib>

using boost::asio::ip::tcp;

int main() {
try {
// HERE
const char* host = std::getenv("SERVER_HOST");
const char* port = std::getenv("SERVER_PORT");

if (!host || !port) {
std::cerr << "Please set SERVER_HOST and SERVER_PORT environment variables\n";
return 1;
}

boost::asio::io_context io_context;

// Создаем и соединяем сокет
tcp::socket socket(io_context);
tcp::resolver resolver(io_context);
boost::asio::connect(socket, resolver.resolve(host, port));

// Отправляем тестовое сообщение
std::string message = "Hello from Boost.Asio client!\n";
boost::asio::write(socket, boost::asio::buffer(message));

// Читаем ответ (до символа новой строки)
boost::asio::streambuf response;
boost::asio::read_until(socket, response, '\n');

// Выводим ответ
std::istream is(&response);
std::string reply;
std::getline(is, reply);
std::cout << "Server replied: " << reply << std::endl;

} catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n";
return 1;
}

return 0;
}


Всего две строчки и никакой мороки! Очень удобная и полезная функция.

Explore your enviroment. Stay cool.

#cpp11
  • 👍 39
  • ❤ 12
  • 🔥 9
  • ❤‍🔥 3
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →