Кракозябры вместо русских букв в консольной программе на C почти всегда означают, что вызов setlocale либо отсутствует, либо передан неверный параметр, либо кодировка консоли не совпадает с кодировкой исходного файла. Без установки локали стандартная библиотека C работает в минимальном режиме "C", где корректно обрабатываются только символы базовой ASCII-таблицы.

В этой статье разберём, как работает setlocale, какие категории локали существуют, чем отличается поведение функции в Windows и Linux, и почему даже правильный вызов иногда не убирает «иероглифы» в терминале.

Что делает setlocale и как устроен её синтаксис

Функция setlocale объявлена в заголовочном файле <locale.h> и имеет два аргумента: категорию локали и строку с именем локали. Прототип выглядит так:

#include <locale.h>

char *setlocale(int category, const char *locale);

Первый аргумент определяет, какую часть локали вы хотите изменить — от формата чисел до правил сравнения строк. Второй аргумент задаёт конкретную локаль: например, "Russian" в Windows или "ru_RU.UTF-8" в Linux. Если передать пустую строку "", будет применена локаль из переменных окружения пользователя — это обычно самый переносимый вариант.

Функция возвращает указатель на строку с именем установленной локали либо NULL, если запрошенная локаль недоступна в системе. Это возвращаемое значение стоит проверять, особенно на Linux, где нужная локаль может быть просто не сгенерирована.

💡

Всегда проверяйте возвращаемое значение setlocale: если оно равно NULL, локаль не установилась, и дальнейшие манипуляции с кодировкой бессмысленны.